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

后端 未结 6 2161
傲寒
傲寒 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:24

    Consider that code is not just to be written once but it evolves over time.

    Lets assume you wrote the code and now my task would be to refactor it. For some reason I want to replace MyClass with YourClass and lets say they have the same interface. I would simply have to replace any occurence of MyClass with YourClass to arrive at this:

    /* Version 1: SomeOtherHeader.hpp */
    
    #pragma once
    #include "YourClass.hpp"
    
    void func(const YourClass& a, const std::vector& b);
    

    I did everything correct, but still the code would fail to compile (because YourClass is not including std::vector). In this particular example I would get a clear error message and the fix would be obvious. However, things can get messy rather fast if such dependencies span across several headers, if there are many of such dependencies and if the SomeOtherHeader.hpp contains more than just a single declaration.

    There are more things that can go wrong. Eg the author of MyClass could decided that they actually can drop the include in favor of a forward declaration. Also then SomeOtherHeader will break. It boils down to: If you do not include vector in SomeOtherHeader then there is a hidden dependency, which is bad.

    The rule of thumb to prevent such problems is: Include what you use.

提交回复
热议问题