1

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

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

如果我错了,请纠正我(我不太了解,这就是为什么一切都只是一个假设):

  1. 那么,在向前声明 STL 上可用的类型时,代码可移植性(对于那些真正希望他们的代码独立于平台的人)有什么影响?(我只知道vectorMSDN 建议的类型可以向前声明但不能保证随时工作)。

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

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

  4. 而且,你能告诉我为什么我应该(不应该)在我的标题中包含 STL 吗?

4

4 回答 4

2

使用 PIMPL 习惯用法在公开/导出 STL 类型的标头上创建编译防火墙:详细信息

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 类型。
于 2013-05-29T05:01:35.543 回答
2

那么在向前声明 STL 上可用的类型时,在代码可移植性方面(对于那些真正希望他们的代码独立于平台的人)有什么影响?

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

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

也许更长的编译时间?再次,请参阅上面的答案。

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

大多数情况下和 AFAIK,DLL 只“存储”类的方法定义。您仍然需要在.h文件中包含 STL 标头。

而且,你能告诉我为什么我应该(不应该)在我的标题中包含 STL 吗?

您应该这样做,因为您几乎总是想使用 STL。来到Lounge<C++>,你一定会大开眼界。

于 2013-05-29T05:02:09.717 回答
1

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

于 2013-05-29T04:57:10.503 回答
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(); }
于 2020-07-17T21:58:23.460 回答