C ++在头文件中包含STL

时间:2013-05-29 04:53:46

标签: c++ stl

在头文件中包含STL是一个坏或好主意?其中你将它们用作你自己定义的类的成员变量。

我的假设是,有些人真的希望他们创建的库在C ++标准库上非常独立。所以他们被迫再次重写类似于C ++ STL中可用功能的类型,而其他人试图在他们的头文件中声明它们将在以后需要的类型。其他人认为这是一种不好的做法,根本不是一个好主意。

如果我错了,请纠正我(我不知道这就是为什么所有这只是一个假设):

  1. 那么在前向声明STL上可用的类型时,代码可移植性(对于那些真正希望其代码与平台无关的人)的影响是什么?(我只知道{{1}的类型MSDN建议可以向前声明,但不能保证始终有效。)

  2. 如果我在头文件中包含STL,可能存在什么问题?这会影响我的代码的可移植性吗?

  3. 如果我在我的DLL的头文件中包含STL并将该DLL带入其他计算机,我会遇到什么问题怎么办?

  4. 而且,你能否给我一个启示,为什么我应该(不应该)在我的标题中加入STL?

4 个答案:

答案 0 :(得分:2)

使用PIMPL惯用法在公开/导出STL类型的标题上创建编译防火墙:Details

class MyList{
public:
//Some functions
private:
std::vector<int> _content;
};

如果你在Vs2012中创建MyList但是组件是在VS2008中构建的,那么VS2008中的代码将按照STL 2008预期内存布局,但布局将是STL 2012的布局。这将产生许多问题。

  1. 您的组件无法跨编译器移植,更不用说平台了。使用std :: vector作为成员变量在VS2008中构建的组件将具有与VS2012中编译的相同的大小。
  2. 是的,在大多数情况下,您的代码将兼容编译器,除非您使用的是旧版本中更新的STL功能。
  3. 只要你在另一台计算机上拥有dll的运行时就没问题。
  4. 对于可重用代码,您不应该跨dll /组件边界使用stl类型。

答案 1 :(得分:2)

  

那么代码可移植性的影响是什么(对于那些   真的希望他们的代码在平台上独立)   声明STL上可用的类型?

始终使用标准C ++和标准库是可移植性的标志。

  

如果我在头文件中包含STL,可能存在什么问题?和   这会影响我的代码的可移植性吗?

编译时间可能更长?再次,请看上面的答案。

  

如果我在我的DLL的头文件中包含STL并带来该DLL,该怎么办?   在其他电脑中,我会遇到什么问题?

主要是AFAIK,DLL只“存储”类的方法定义。您仍需要在.h文件中包含STL标题。

  

而且,你能给我一个启示,为什么我应该(不应该)   在我的标题中加入STL?

你应该,因为你几乎总是想要使用STL。来Lounge,你一定会受到启发。

答案 2 :(得分:1)

如果您使用的是标准C ++ STL库,那么您可能没有移植问题,因为Microsoft Visual C ++和g ++都支持这些。 除非你是非标准的STL标题,否则你会遇到问题。

答案 3 :(得分:1)

不惜一切代价避免标题中的STL:

  1. STL包含实现细节。留给源代码。
  2. 标头是您的API,您只想公开函数,结构和接口。
  3. 您可能希望以不同的方式编译和链接库-如果说在调试中分配并在发行版中删除内存,则会导致跨模块错误。因此,请勿使用std :: string通过API传递信息。
  4. 您开始只包含一个来自STL的标头,您会发现其他模块也开始泄漏。最后,您将以STL毒化所有内容,没有真正的接口,并且构建时间应在数分钟之内,而应该在数秒之内。

STL如何改进以下API? IDog的消费者不需要知道狗的内部结构,只需知道它的吠叫即可。

struct IDog
{
     virtual void Bark() = 0;
     virtual void Free() = 0;
}

IDog* CreateDog(); 

In your source code you might have

struct Dog: IDog
{
    Dog() {...}
    std::vector<VocalChord> vocalChords; 
    void Bark() override { Resonate(vocalChords); }
    void Free() { delete this; }
};

IDog* CreateDog() { return new Dog(); }