Explicit direct #include vs. Non-contractual transitive #include

后端 未结 6 2157
傲寒
傲寒 2021-02-12 12:47

Say we have this header file:

MyClass.hpp

#pragma once
#include 

class MyClass
{
public:
    MyClass(double);

    /* ... */

private:
            


        
6条回答
  •  情书的邮戳
    2021-02-12 13:11

    If your MyClass has a member of type std::vector then the header that defines MyClass needs to #include . Otherwise, the only way users of MyClass can compile is if they #include before including the definition of MyClass.

    Although the member is private, it is still part of the class, so the compiler needs to see a complete type definition. Otherwise, it cannot do things such as compute sizeof(MyClass), or instantiate any MyClass objects.

    If you want to break the dependency between your header and there are techniques. For example, the pimpl ("pointer to implementation") idiom.

    class MyClass 
    {
    public:
        MyClass(double first_value);
    
        /* ... */
    
    private:
        void *pimpl;
    };
    

    and, in the source file that defines members of the class;

    #include 
    #include "MyClass.hpp"
    
    MyClass::MyClass(double first_value) : pimpl(new std::vector())
    {
    
    }
    

    (and also, presumably, do something with first_value, but I have omitted that).

    The tradeoff is that every member function that needs to use the vector needs to obtain it from the pimpl. For example, if you want to get a reference to the allocated vector

    void MyClass::some_member_function()
    {
        std::vector &internal_data = *static_cast *>(pimpl);
    
    }
    

    The destructor of MyClass will also need to release the dynamically allocated vector.

    This also limits some options for the class definition. For example, MyClass cannot have a member function that returns a std::vector by value (unless you #include )

    You'll need to decide if techniques like the pimpl idiom are worth the effort to make your class work. Personally, unless there is some OTHER compelling reasons to separate the class implementation from the class using the pimpl idiom, I would simply accept the need for #include in your header file.

提交回复
热议问题