2

我经常使用前向声明;它们有助于避免许多#includes,缩短编译时间等等。但是如果我想在标准库中前向声明一个类怎么办?

// Prototype of my function - i don't want to include <vector> to declare it!
int DoStuff(const std::vector<int>& thingies);

我听说 forward-declare 是禁止/不可能的std::vector。现在这个对一个不相关问题的回答建议用这种方式重写我的代码:

东西.h

class VectorOfNumbers; // this class acts like std::vector<int>
int DoStuff(const VectorOfNumbers& thingies);

东西.cpp

// Implementation, in some other file
#include <vector>
class VectorOfNumbers: public std::vector<int>
{
    // Define the constructors - annoying in C++03, easy in C++11
};

int DoStuff(const VectorOfNumbers& thingies)
{
    ...
}

现在,如果我在整个项目中使用VectorOfNumbers而不是std::vector<int>在所有上下文中使用,一切都会好起来的,我不再需要#include <vector>在我的头文件中!

这种技术有很大的缺点吗?能够提前申报的收益能否vector超过它们?

4

5 回答 5

6

如果您曾经将 aVectorOfNumbers作为 a删除std::vector<int>(并且由于您使用了公共继承,此转换是隐式的),您就进入了未定义行为的领域。这可能比人们怀疑的更可能意外发生。

我个人从未注意到仅vector在需要的地方包含会显着降低编译速度,但如果您真的想隔离包含,请使用不了解底层容器类型 ( vector) 的客户端 API 接口并将vector包含添加到单个源中文件。

于 2011-10-25T20:57:40.360 回答
3

我不会这样做的原因:

const std::vector<int>& a = a_3rd_party_lib::get_data(); // this type is out of your control
DoStuff(a); // you cannot pass it to this function! 
于 2011-10-25T21:04:28.087 回答
0

您包含<vector>在头文件中。标<vector>头将被构建以防止多次包含,因此您只需将它包含在您需要的任何地方。

于 2011-10-25T20:53:25.663 回答
0

这适用于类的接口,但不适用于实现。如果您的类有任何vector必须#include <vector>的成员,否则类定义将无法编译。

于 2011-10-25T20:58:56.120 回答
0

您可以使用组合代替继承:

// Implementation, in some other file
#include <vector>
class VectorOfNumbers
{
    public:

    std::vector<int>& container;

    VectorOfNumbers(std::vector<int>& in_container)
        : container(in_container)
    {
    }
};

int DoStuff(const VectorOfNumbers& thingies)
{
    std::sort(thingies.container.begin(), thingies.container.end());
    // ...
}

缺点是每次访问都有额外的变量名。

此外,您需要将此实现放在 cpps 包含的头文件中,以便他们知道可以使用 VectorOfNumbers 做什么。

本质上,只是为你的向量制作一个包装器。这就像PImpl的轻量级版本(我们只关心避免头依赖,因此我们不需要完整的指针解耦)。它避免了 Mark B 和 ybungalobill 提出的问题。

但我认为这真的不值得。

于 2017-09-01T23:26:48.227 回答