2014-10-03 139 views
1

我知道了,如果你声明例如全球范围内的一个int,矢量和原始类型初始化

int x; //默认为0;

和在局部范围内,

void f() { 
    int x; //undefined 
} 

然而,如果我们使用一个矢量在全局或局部范围:

矢量<INT> V(3); //使用int的默认构造函数将v初始化为{0,0,0}。

我们可以通过做这个默认的initialise INT像载体的元素在局部范围内:

INT X = INT(); //默认为0

我想如果我们使用int的默认构造函数,它将被分配到堆中。

  1. 为什么不能在T x这样的本地范围内初始化一个原始类型?或
  2. 在本地范围内,为什么向量(不知道其他容器)使用元素的默认构造函数,而不是像int声明一样使它们不初始化?
  3. 当前方法对这两种类型有什么好处?为什么他们以不同的方式初始化?这是关于表现吗?
+0

1)因为那是语言如何指定它。 2)因为这是C +标准如何说'std :: vector'应该工作。 – juanchopanza 2014-10-03 08:16:29

回答

2

这就是出于“性能”原因,因为C++人希望20世纪80年代的C族人没有任何理由抱怨“为我们不需要的东西付钱”。这是C++的原则之一,不会为不使用的东西支付(运行时)成本。因此,默认情况下,旧式POD类型未初始化,尽管具有构造函数的类和结构始终具有其中一个构造函数。

如果我今天指定它,我会说在本地范围内的int x;将被默认初始化(为0),并且如果你想避免这种情况,你可以说类似int x = std::noinit;的东西。现在是这个为时已晚,但其实我已经在某些类类型做它时,性能非常看重:

class SuperFast 
{ 
    struct no_init_t {}; 
public: 
    no_init_t no_init; 
    SuperFast() : x(0), y(0) {} 
    SuperFast(no_init_t) {} 

private: 
    int x, y; 
}; 

这样,默认的建设将给出一个有效的对象,但如果你有一个严重的理由需要避免这种情况,你可以。你可以使用这种技术,如果你知道你很快就会覆盖一大堆这些对象 - 无需默认构造它们:

SuperFast sf(SuperFast::no_init); // look ma, I saved two nanoseconds! 
+1

如果带有构造函数的类调用它们的默认构造函数,是不是已经违反了这个规则,不支付你不使用的东西的运行时成本? – morbidCode 2014-10-03 08:33:15

+0

@recursivePointer:很好的问题。不,因为需要“非初始化”行为的类可以实现允许它的特殊构造函数。我将编辑我的答案来证明这一点。 – 2014-10-03 08:36:11

+0

因此,换句话说,默认情况下,旧的POD类型未初始化主要是因为c兼容性,并且库中具有构造函数的类不能声明为未初始化。是对的吗? – morbidCode 2014-10-03 08:57:30