我有两个问题
假设有一个基类和几个派生类,派生类将包含所有#include
语句(如#include <iostream>
等)和using
行的基数类。
1.在派生类h中编写基类的#include
语句和using
行是否被认为是一种好习惯。文件无论如何?
2.关于作文的相同问题 - A类有一个B类对象作为成员,在A&#39; h中写B s
#include`语句是一个好习惯。文件无论如何?
谢谢!
答案 0 :(得分:2)
我认为让每个include
文件实际上#include
所需的任何定义都是一个好习惯,这样在您的主程序中,您可以#include
最深入派生类,而不必为类所需的定义添加额外的#include
语句。
您可以让类定义包含指针到以前未定义的类,如下所示:
class forward_ref;
class myClass :
Public:
myClass(){}
forward_ref* ptr_to_forward_ref;
};
答案 1 :(得分:2)
假设有一个基类和几个派生类, 派生类将包含所有#include语句(如
#include <iostream>
等)并使用基类的行。
完全没有。
首先,您不应该将using
行放在头文件的顶级范围内。这是一个普通的初学者&#39;错误。
第二,是什么让你认为派生类需要基类的所有#include
?派生类头文件需要包含基类头文件,派生类实现文件需要包含派生类头文件。
这已经为您提供了所有包含。
base.h:
#include <string>
class Base
{
// ...
virtual std::string f(); // no `using`
};
derived.h:
#include "base.h"
// no need for <string> here
class Derived : public Base
{
// ...
virtual std::string f();
};
derived.cpp:
#include "derived.h"
// no need for <string> here
std::string Derived::f() // could have used `using std::string`
{
// ...
}
当然,从技术上来说可能以其他方式实际做到这一点,就像这样:
base.h:
// no <string>?!
class Base
{
// ...
virtual std::string f();
};
derived.h:
#include "base.h" // still no <string>?!
class Derived : public Base
{
// ...
virtual std::string f();
};
derived.cpp:
#include <string> // ah, OK
#include "derived.h"
std::string Derived::f()
{
// ...
}
这只是因为在处理完所有包含之后,编译器没有单独编译头文件而只编译整个编译单元(〜= .cpp文件)。
但请谈谈可怕的编程风格。你为什么要强迫从你的类派生的每个人都包含额外的标题?
2.关于组合的相同问题 - 类A有一个B类对象作为成员,编写Bs #include`语句是一个好习惯 在A&#39; h。文件无论如何?
这取决于。如果A
的标题需要访问任何B
成员,那么您必须使用包含,在这种情况下,您只需要包含所需内容在bh中,让啊#include "b.h"
。
如果A
的标题只需要指针或对B
的引用,或只是返回值,那么您可以使用前向声明为了加快编译速度。当然,加速编译并不是C ++初学者应该关心的事情,因为在开发需要数小时构建的软件之前,很多时间都会过去。)
无论如何,为了完整性&#39;缘故:
A.H:
class B; // forward declaration, no #include
class A
{
// ...
B f();
B *ptr;
B &ref;
};
a.cpp:
#include "a.h"
#include "b.h" // need the include here
B A::f()
{
B obj;
return obj;
}
b.h:
class B
{
// ...
};
答案 2 :(得分:1)
在回答问题2时:通常您会在A的头文件中包含B类头文件(因此A中所需的所有包含将自动包含在内)。
然而,正如Logicrat的回答所指出的那样,你也可以在A中只包含一个指向B的指针。在这种情况下,你可以在A.h中使用B的前向声明,而不是包括B.h.这样做的缺点是所有需要使用B的函数必须进入A.cc(肯定必须包含B.h)。优点是您可以大大减少头文件中的代码数量(因为每个#include在编译之前将整个头文件复制到当前文件中),这可以加快编译时间。