派生类中相同的#include语句

same #include statements in derived classes

本文关键字:#include 语句 派生      更新时间:2023-10-16

我有两个问题

假设有一个基类和几个派生类,派生类将具有基类的所有#include语句(如#include <iostream>等)和using行。1. 是否认为在派生类h.文件中编写基类的#include语句和using行是一种良好的实践?

2。同样的问题关于组合-类A有一个类B的对象作为成员,写B s #include语句在A的h.文件是一个很好的做法吗?

谢谢!

我认为让每个include文件实际上#include它需要的任何定义是一个很好的做法,这样在你的主程序中,你可以#include你最深入的派生类,而不必为类需要的定义有额外的#include语句。

可以让类定义包含指针指向先前未定义的类,如下所示:

class forward_ref;
class myClass :
Public:
 myClass(){}
 forward_ref* ptr_to_forward_ref;
};

假设有一个基类和几个派生类派生类将具有所有的#include语句(例如#include <iostream>等)和使用基类的行。

一点也不。

首先,你是不是应该把using行在头文件的顶级作用域。这是初学者常犯的错误。

第二,是什么让你认为派生类需要基类的所有#include ?派生类的头文件需要包含基类的头文件,派生类的实现文件需要包含派生类的头文件。

这已经给了你所有的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的对象作为成员,写b# include语句是不是一个好做法在A的h文件里

视情况而定。如果A的头文件需要访问B的任何成员,那么你必须使用include,在这种情况下,你只需要在b.h中包含你需要的东西,让a.h #include "b.h"

如果A的头文件只需要一个指向B的指针或引用,或者只是一个返回值,那么您可以使用前向声明,以潜在地加快编译速度。当然,加快编译速度并不是c++初学者应该关心的事情,因为大量的时间将会过去,直到你开发出需要数小时构建的软件:)

无论如何,为了完整起见:

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:通常情况下,你会在A的头文件中包含类B的头文件(因此A所需的所有包含将自动包括在内)。

然而,正如Logicrat的回答所指出的那样,您可以选择在a中只包含指向B的指针。在这种情况下,您可以在A.h中使用B的前向声明,而不是包括B.h。这样做的缺点是所有需要使用B的函数都必须在A.cc中(这肯定必须包括B.h)。其优点是可以大大减少头文件中的代码量(因为每个#include都会在编译前将整个头文件复制到当前文件中),这可以加快编译时间。