2011-10-25 48 views
2

我已经使用了前向声明;他们帮助避免了许多问题,提高了编译时间,而不是什么。但是如果我想要在标准库中声明一个类呢?涉及std :: vector的前向声明

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

我听说它是​​被禁止/不可能前瞻性声明std::vector。现在this answer to an unrelated question建议以这种方式重写我的代码:

stuff.h

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

stuff.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的收益是否超过它们?

回答

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! 
+1

不能VectorOfNumbers只是提供一个转换ctor从它的底层std :: vector类型? –

+0

@Martin:它会复制整个事情。你不想要这个,是吗? – ybungalobill

0

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

+2

这是如何回答OP的问题? – ildjarn

6

如果您曾将VectorOfNumbers作为std::vector<int>删除(并且由于您使用了公有继承,此转换是隐式的),您已经进入了未定义行为的领域。这可能比意想不到的事情更可能发生。

我从不亲自注意到从刚包括vector在需要的地方显著编译放缓,但如果你真的想要隔离包括,使用客户端API接口,不知道底层的容器类型(vector)和PIMPL vector包含在单个源文件中。

0

这适用于类的接口,但不适用于实现。如果您的班级有任何vector成员,您必须#include <vector>或者类定义不会编译。

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提出的问题。

但我认为这不值得。