`Base * b = new Base;`vs`Base * b = new Base();`没有定义我自己的构造函数

时间:2010-09-13 03:48:31

标签: c++ constructor

如果我没有定义自己的构造函数,那么Base *b = new Base;Base *b = new Base();之间是否存在差异?

3 个答案:

答案 0 :(得分:8)

初始化是标准中遵循的PITA ......然而,两个已经存在的答案在他们错过的内容中是不正确的,这使得他们确认没有差异。

在没有用户定义构造函数的类中调用new Tnew T()之间存在巨大差异。在第一种情况下,对象将是 default-initialized ,而在第二种情况下,它将是`value-initialized *。如果对象包含任何POD子对象,则第一个将保留未初始化的POD子对象,而第二个将子对象设置为0。

struct test {
   int x;
   std::string s;
};
int main() {
   std::auto_ptr<test> a( new test );
   assert( a->s.empty() ); // ok, s is string, has default constructor
                           // default constructor sets it to empty
// assert( a->x == 0 );    // this cannot be asserted, the value of a->x is
                           // undefined
   std::auto_ptr<test> b( new test() );
   assert( b->s.empty() ); // again, the string constructor sets to empty
   assert( b->x == 0 );    // this is guaranteed by *value-initialization*
}

对于漫长的道路...用户定义的类的 default-initialize 意味着调用默认构造函数。在没有用户提供的默认构造函数的情况下,它将调用隐式定义的默认构造函数,这相当于具有空初始化列表和空体(test::test() {})的构造函数,这反过来将导致每个非POD子对象的默认初始化,并使所有POD子对象保持未初始化状态。由于std::string有一个用户(通过包含标准库编写器的某个用户定义)提供的构造函数,它将调用这样的构造函数,但它不会对{{{{{ 1}}成员。

也就是说,对于用户提供的默认构造函数,xnew T是相同的。对于没有这种构造函数的类,它取决于类的内容。

答案 1 :(得分:3)

编辑:看到@David的答案 - 这是错的,但我不能删除它因为它被接受

两种情况都没有区别 - 如果你定义自己的构造函数也没关系。

唯一的区别是对于原始类型(即intfloat),添加()会将值初始化为零。 (Demonstration on Codepad

请参阅此示例(输出位于codepad

#include <iostream>

struct ConstructorChecker
{
    ConstructorChecker()
    {
        std::cout << "Hey look! A new constructor checker!" << std::endl;
    }
};

struct BasicClass
{
};

int main()
{
    //Note constructor called in both cases.
    ConstructorChecker *one = new ConstructorChecker;
    delete one;
    ConstructorChecker *two = new ConstructorChecker();
    delete two;
    //Same deal -- just because the compiler provides the constructor doesn't mean
    //it behaves any differently.
    BasicClass *basic = new BasicClass;
    delete basic;
    BasicClass *basic2 = new BasicClass();
    delete basic2;
    return 0;
}

答案 2 :(得分:-1)

正如比利所说,两者都是同一个。

这称为'值初始化语法'($ 8.5 / 7)。

  

初始化程序为的对象   空的圆括号,即(),   应进行价值初始化。