C++ 向量和基元类型初始化

C++ 向量和基元类型初始化,c++,vector,C++,Vector,我了解到,如果你在全局范围内声明一个int int x//默认为0 在局部范围内, void f() { int x; //undefined } 但是,如果我们在全局或局部范围内使用向量: 向量v(3)//使用int的默认构造函数将v初始化为{0,0,0} 通过执行以下操作,我们可以在局部范围内默认初始化int-like向量的元素: int x=int()//默认为0 我认为如果我们使用int的默认构造函数,它将被分配到堆中 为什么不能在局部作用域中对原语类型进行默认初始化,如t x

我了解到,如果你在全局范围内声明一个int

int x//默认为0

在局部范围内,

void f() {
    int x; //undefined
}
但是,如果我们在全局或局部范围内使用向量:

向量v(3)//使用int的默认构造函数将v初始化为{0,0,0}

通过执行以下操作,我们可以在局部范围内默认初始化int-like向量的元素:

int x=int()//默认为0

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

  • 为什么不能在局部作用域中对原语类型进行默认初始化,如t x;?或
  • 在局部范围内,为什么向量(不知道其他容器)使用元素的默认构造函数,而不像int声明那样不初始化它们
  • 当前方法对这两种类型有什么好处?为什么它们以不同的方式初始化?这是关于性能的吗
  • <> P>这是因为“性能”原因,因为C++用户希望C++的人返回到1980,没有理由抱怨“为我们不需要的东西付费”。这是C++的一个原则,不为不使用的东西支付(运行时)费用。因此,旧式POD类型在默认情况下是未初始化的,尽管带有构造函数的类和结构总是调用其中一个构造函数

    如果我今天指定它,我会说
    intx将被默认初始化(为0),如果您想避免这种情况,可以说类似于
    intx=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) 因为这就是语言指定它的方式。2) 因为这就是C+标准所说的
    std::vector
    应该如何工作的。如果调用int构造函数,它将不会被分配到堆上。只有在使用
    new
    关键字时,才会出现这种情况。您可以使用
    intx()
    int x=int()
    。如果有构造函数的类调用它们的默认构造函数,那么不为您不使用的东西支付运行时成本不是已经违反了这一点吗?@recursivePointer:问得好。不,因为想要“No init”行为的类可以实现一个允许它的特殊构造函数。我将编辑我的答案来演示这一点。换句话说,旧的POD类型在默认情况下是未初始化的,主要是因为c兼容,库中具有构造函数的类不能声明为未初始化。是吗?基本上——标准库人员没有为他们的类型提供“noinit”构造函数,可能是因为它不适合OOP但有时对于最高性能,你必须违反封装,不变量等。我意识到这有点自相矛盾,但欢迎来到C++!