C++用户定义的空默认构造函数vs隐式或默认的默认构造函数

1 c++ constructor initialization default-constructor

我正在使用Visual Studio 2013.

我有以下代码

class Foo{
public:
     Foo(){};
     Foo* fPtr;
     float f;
};

int main()
{
    Foo foo1; // No Warning. fPtr is initialized to NULL, f is set to 0.0.
    Foo foo2(foo1); // Compiles fine. Uses compiler generated copy constructor
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在考虑相同的代码,但没有用户定义的默认构造函数.

class Foo{
public:
               // No user defined default constructor, or equivalently
               // Foo() = default;
     Foo* fPtr;
     float f;
};

int main()
{
    Foo foo1; // Neither fPtr nor f are initialized, both contain garbage.
   //Foo foo2(foo1); // error C4700: uninitialized local variable 'foo1' used
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为用户定义的默认构造函数和隐式定义的默认构造函数是等价的,但在我看来它们不是.

编译器如何定义默认构造函数?

在这种情况下,我对使用编译器定义的默认构造函数持谨慎态度,并且总是提供我自己的,即使有时是空的默认构造函数.我误会了什么吗?

son*_*yao 5

在实现时,隐式定义的默认构造 函数与具有空主体和空初始化列表的用户定义构造函数执行相同的操作.

如果隐式声明的默认构造函数未定义为已删除,则编译器会定义(即,函数体生成并编译),如果使用了odr,则它与用户定义的构造函数具有完全相同的效果空体和空初始化列表.

Foo foo1; // No Warning. fPtr is initialized to NULL, f is set to 0.0.
Run Code Online (Sandbox Code Playgroud)

号不仅为第二代码示例,即使对于第一代码示例,foo1.fPtr并且foo1.f不被初始化; 空的用户定义构造函数根本不初始化任何成员.

关于编译器警告,似乎MSVS认为如果提供并调用了用户定义的构造函数,则可以认为该对象已经初始化.但是你需要确保构造函数执行或不执行预期的操作.

请注意,它们仍然有一些微妙的不同副作用; 例如列表初始化值初始化,(但不是这里使用的默认初始化).例如

Foo foo1{};
Run Code Online (Sandbox Code Playgroud)

然后对于第一种情况,将调用用户定义的默认构造函数; 因为它什么都不做foo1.fPtr,foo1.f仍然是未初始化的; 但对于第二种情况,集合初始化将被执行(因为用户定义的构造函数的缺失),那么foo1.fPtrfoo1.f将值初始化.ie foo1.fPtr初始化为nullptr,foo1.f初始化为0.

  • @Hrachya_h不,他们没有初始化,例如http://rextester.com/JVFH58493. (2认同)