作为C ++的新手,我正在尝试对#include方法进行排序。
我遵循以下示例中详述的某些指导原则。到目前为止,这已经为我做了(整个项目一直在编译:)),但我担心将来会遇到问题,因此我的问题是 - 这是一个正确的方法吗?还有更好的吗?解释它的基本逻辑是什么?
考虑以下示例:
Father.h
#pragma once
class Father
{
// Some implementation
};
ClassA.h
#pragma once
#include "Father.h"
#include "StructC.h"
class ClassB;
class ClassA : public Father
{
StructC struct_c_obj;
ClassB class_b_obj;
// Some implementation
};
ClassA.cpp
#include "Father.h"
#include "ClassB.h"
#include "StructC.h"
// Some implementation
ClassB.h 和 ClassB.cpp
没有包含的类
StructC.h
struct StructC {
// Some implementation
};
我遵循以下准则:
#pragma once
声明class ClassB;
decleration,在ClassA.cpp中具有#include "ClassB.h"
这可能是一套笨拙的指导方针,对底层逻辑几乎一无所知,所以我可能会有一些愤怒......带上它,我 am 尝试在这里学习......:)
更新
答案 0 :(得分:9)
这些是我个人遵循的指导原则:
ClassA
包含ClassB
,因此需要#include "ClassB.h"
。如果ClassB
类型仅通过指针或引用出现在文件中,则前向引用就足够了ClassA.h
中先包含ClassA.cpp
,然后对以下内容使用任意排序(我使用按字母顺序排序)关于其他方面:
#pragma
不标准,更喜欢include guards std::string
,则 到#include <string>
答案 1 :(得分:1)
#pragma once
是非标准的(但受到广泛支持),因此您可能/可能不想使用#ifdef
警卫。
至于你是否需要#include
任何特定标题,这取决于。如果代码只需要一个前向声明,那么通过向前声明类型来避免导入。
除了模板内容之外,我认为在头文件中放置长函数定义可能并不太好。
话虽如此,我认为ClassA.h
实际上应该包含ClassB.h
,因为ClassA.h
的任何用户(可能使用ClassA
)都必须ClassB.h
}。好吧,如果它正在做分配它的任何事情。
答案 2 :(得分:1)
当Class具有此类型的数据成员时,不要使用Class的前向声明。 当它有一个指向B类的指针时,可以使用它,如:
#pragma once
#include "Father.h"
#include "StructC.h"
class ClassB;
class ClassA : public Father
{
StructC struct_c_obj;
ClassB *class_b_obj;
// Some implementation
};
答案 3 :(得分:0)
我从Python中获得的一件事(因为它是绝对的要求)是“在你使用它的模块中导入(包括)它”。这将使您在拥有或不具备定义时避免麻烦。
答案 4 :(得分:0)
我通常不使用pragma once
因为pragma不是标准的。您可能必须将代码移植到未定义的其他编译器,并且您必须使用#ifndef ... #define
惯用法重写每个编译器。
这是因为我直接使用#ifndef ... #define
。
第二件事:在头文件中使用多个包含不是一个好主意:我总是尽量减少它们。如果你有太多的东西,每次你改变其中一个小东西时,你将不得不重新编译每个依赖的.cpp文件。
如果是这种情况,我采用 Pimpl 习语,你可以找到描述here(参见C ++示例)。无论如何,如果项目的规模不是那么大,我认为你的方法是正确的。