头文件应该包括其他头文件,还是由实现来决定

Should a header file include other header files, or leave it to the implementation?

本文关键字:文件 实现 决定 包括 其他      更新时间:2023-10-16

因此,我可以编译所有内容,并且我理解(我认为)include保护程序如何防止相同的定义被拉两次,但我不知道的是,如果我的类文件已经包括了它,我的头文件是否也应该包括它所使用的类的头文件。

Child.hpp

// Child.hpp
#ifndef CHILD_H
#define CHILD_H
class Child {
    public:
        Child();
};
#endif

Child.cpp

// Child.cpp
#include "Child.hpp"
Child::Child() {
    // example
}

Parent.hpp

我是否也应该在这里包括Child.hpp,尽管它已经包含在Parent.cpp中了?我知道头部保护可以防止Child被定义两次,但这被认为是最佳实践吗?还是我应该在这里只包含Child.hpp?

// Parent.hpp
#ifndef PARENT_H
#define PARENT_H
class Parent {
    public:
        Parent();
        Parent(Child child);
};
#endif

Parent.cpp

// Parent.cpp
#include "Child.hpp"
#include "Parent.hpp"
int main() {
    Parent parent;
    return 0;
}
Parent::Parent() {
    // example
}
Parent::Parent(Child child) {
    // example
}

我们在课堂上只举了一个例子,它本质上说在Parent.cpp中应该包括Parent.hpp(有意义)和Child.hpp

我似乎想在Parent.hpp中包含Child.hpp,因为Parent类依赖于Child类,但无论哪种方式,都会包含Child.hpp

如果Parent具有Child的任何实例,则是的,必须将标头包含到Child.hpp中。

class Parent {
    public:
        Parent();
        Parent(Child child);     // Need full include, complete type used
        Child c;                 // Need full include, complete type used
};

如果Parent只有指向Child指针引用,那么只需向前声明Child,然后在Parent.cpp中执行include就可以了。

class Child;                     // Forward declaration
class Parent {
    public:
        Parent();
        Parent(Child* child);    
        Child* pc;               // Incomplete type ok if pointer or reference
};

通常,除非绝对必要,否则应避免在其他标头中包含标头。充其量,它会不必要地增加构建时间。最坏的情况是,它可能导致循环依赖。