0

我正在阅读有效 C​​++ 的书,其中有几页说:

如果您在 C++ 的 C 部分并且初始化可能会产生运行时成本,则不能保证会发生。如果你跨入 C++ 的非 C 部分,事情有时会发生变化。这解释了为什么数组(来自 C++ 的 C 部分)不一定保证其内容已初始化,但向量(来自 C++ 的 STL 部分)却可以。

我想知道为什么来自 c++ 的 c 部分的数组不能保证被初始化,但向量是?c部分的数组不是内置类型吗?但是为什么向量(来自 C++ 的 STL 部分)保证被初始化?

4

4 回答 4

5

因为这就是标准所说的。在 C++ 规范的早期,就决定改变 C 中定义的类型的工作方式。因此,只有在 1) 类型具有构造函数,2) 存在显式初始化或 3) 它具有静态生命周期时,T[]才会初始化数组 ( )。T由于 std::vector不是从 C 继承的,因此没有 C 的先例需要关注。而且由于您可以对向量执行的某些操作需要复制,因此必须对其进行初始化。复制未初始化的值是未定义的行为。

请注意,在 C++11 中,std::array遵循 C 规则。(这样做是为了允许聚合初始化。)

于 2013-09-20T08:56:53.327 回答
1

当您定义int a[10];(非静态)时,则内容a初始化。这就是 C 和 C++ 的设计方式。你没有要求,你不明白。(如果你想要一个初始化的数组,你会说int a[10]();。)

std::vector<int>在 C++ 中,无论您做什么,该类都被设计为始终具有明确定义的语义。因此,当您定义 时std::vector<int> v(10),您将获得十个值初始化(即归零)元素(类似于上面的第二个示例)。

但是,无论如何,不​​要为不需要的东西付费,后者可能是糟糕的 C++。您通常使用的是reserve,就像在 C 中一样,它创建内存但不创建对象,并且在需要时创建对象并且不需要进一步分配:

std::vector<int> v;            // no allocation (hopefully)
v.reserve(10);                 // one single allocation

for (int i = 0; i != 10; ++i)
    v.push_back(i);            // no allocations, guaranteed

简而言之:C 只知道memoryC++ 将存储对象的概念分开。这种更细粒度的模型伴随着更丰富的界面。在 C 语言中,您根本无法表达“我可能需要这个存储,但我还没有任何东西可以放入其中”的概念。

于 2013-09-20T08:59:41.473 回答
0

类似 C++ 的类型vector实际上是类,它们有一个内置的构造函数——当我们创建这种类型的变量时会自动调用一个过程,并且 STL 容器的构造函数可以初始化该变量。而当你使用来自 C 的东西时,它就简单多了:当你创建一个变量时,你所做的只是,从广义上讲,为你自己的需要占用一些内存。如果这个内存中有东西,它会留在那里,因为创建这种类型的变量(比如一个简单的数组)只包括为它寻找内存。

于 2013-09-20T08:59:12.007 回答
-1

不同之处在于 C 风格的数组是一种语言原语,很像 int 或 float,因此它们的规则基本上是在声明时什么也不做。

int i;

在这里,我将取之前在内存中这个位置的任何值。

但是向量(和其他 STL 容器)是对象,并且对象有一个构造函数,通常可以做一些工作。

std::vector<int> v1(10); //create a vector of 10 ints, not initialized, just like int[10] would do
std::vector<int> v2(10, 0);//create a vector of 10 ints, all initialized to zero.
于 2013-09-20T08:53:15.150 回答