c++ - 成员类与#includes

标签 c++ class header-files

我最近发现在您的头文件中包含 #include 是一种不好的形式,因为任何使用您的代码的人都会获得他们不一定想要的所有这些额外包含。

但是,对于将成员变量定义为另一个类的类型的类,还有什么选择呢?

例如,我最长的时间是按以下方式做事:

/* Header file for class myGrades */
#include <vector>           //bad
#include "classResult.h"    //bad

class myGrades
{
    vector<classResult> grades;
    int average;
    int bestScore;
}

(请原谅这是一个高度人为的例子)

所以,如果我想去掉 #include 行,有什么方法可以保留 vector 还是我必须在完全不同的方式?

最佳答案

如果您的类直接包含给定类型的数据成员(顺便说一句,不是指向该类型的指针或对该类型的引用),那么您必须有可用的类声明,以便编译器知道如何您的对象实例占用的字节数。这通常意味着您必须#include 头文件。

但是,有一些称为编译器防火墙的技术可以让您以一种方式构建类,使类能够访问适当类型的对象,而无需直接包含它们。其中之一是 pImpl idiom ,其中您的类实现如下所示:

class MyClass {
public:
    /* ... */

private:
    struct Impl;
    Impl* pImpl;
};

在这里,您前向声明一个包含类实现的结构 Impl,然后在类中存储一个指向 Impl 结构的指针。因为在你的类中有一个指针不需要知道被指向的对象的大小,所以这非常好。然后,在 .cpp 文件中,您可以定义 Impl 结构:

struct MyClass::Impl {
    /* ... */
};

您只需按照指向实际字段的 pImpl 指针,就可以实现该类的所有成员函数。这有一个缺点,即所有字段访问都需要指针间接,但如此快速地更改类实现的能力确实使它很有用。

沿着相同思路的另一个选择是使该类成为抽象基类,然后提供一个静态因子函数,该函数返回一个子类化您的基类的对象,该对象实际上包含实现。例如:

class MyClass {
public:
    virtual ~MyClass(); /* Need virtual dtors in polymorphic classes! */

    virtual void doSomething() = 0;
    /* ... etc. ... */

    static MyClass* New(/* ... args ... */);
};

然后,在 .cpp 文件中,您可以定义 MyClass 的具体子类,它实际上完成了所有工作:

class ActualClass: public MyClass {
public:
     void doSomething();
     /* ... etc. ... */

private:
     /* ... data members ... */
}

最后,实现 New 以创建实现类的新实例:

MyClass* MyClass::New(/* ... args ... */) {
    return new ActualClass(/* ... args ... */);
}

希望这对您有所帮助!

关于c++ - 成员类与#includes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4840523/

相关文章:

c++ - Char Star Array 参数未正确终止

c++ - 将 raw operator new、placement new 和 standard delete 结合起来是否合法?

java - 找不到符号错误

c++ - 在类名之后但在开括号之前的引号

c++ - 处理 header 中令人痛苦的长命名空间名称

c++ - 内联函数访问静态?

c++ - OpenGL UV行为异常吗?

c++ - 使用 int vector 元素作为输入的递归方法类

c++ - 已编译库的 header 无法相互访问

Python 的 easy_install 和自定义头文件/库位置