C 用户定义的空默认构造函数与隐式或默认为默认的默认构造函数
C++ User defined empty default constructor vs implicit or default-ed default constructor
我正在使用Visual Studio2013。
我有以下代码
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;
}
现在考虑相同的代码,但没有用户定义的默认构造函数。
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;
}
我认为用户定义的默认构造函数和隐式定义的默认构造函数是等效的,但在我看来它们不是。
编译器确切定义默认构造函数如何工作?
在这种情况下,我谨慎使用编译器定义的默认构造函数,并始终提供自己的默认构造函数,即使有时也可以提供自己的默认构造函数。我是在误解某些东西吗?
在实现时,隐式定义的默认构造函数 die 与带有空白的用户定义的构造函数相同的东西。
如果未定义为删除的隐式默认构造函数,则如果使用ODR使用,则将其定义(即,将函数正文生成和编译),并且与用户的效果完全相同定义的构造函数,带有空体和空初始化器列表。
和
Foo foo1; // No Warning. fPtr is initialized to NULL, f is set to 0.0.
否。不仅对于第二代码示例,即使对于第一代码样本,foo1.fPtr
和foo1.f
也没有初始化;空用户定义的构造函数根本不初始化任何成员。
以及关于编译器的警告,MSV似乎认为如果提供并调用了用户定义的构造函数,则可以认为该对象已被初始化。但是您需要确保构造函数做或不做您预期的事情。
请注意,它们仍然具有一些微妙的副作用。例如列表初始化和价值Intialization(但不是此处使用的默认初始化)。例如
Foo foo1{};
然后,对于第一种情况,将调用用户定义的默认构造函数;因为它没有任何作用foo1.fPtr
,并且foo1.f
仍然非专业化;但是对于第二种情况,将执行汇总初始化(由于用户定义的构造函数缺少),那么foo1.fPtr
和foo1.f
将进行价值initialized。即foo1.fPtr
初始化为nullptr
,foo1.f
初始化为0
。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数