【问题标题】:C++11: Can defaulting default constructor lead to partially initialized class?C++11:默认的默认构造函数会导致部分初始化的类吗?
【发布时间】:2019-06-23 20:39:10
【问题描述】:

在 C++11 及更高版本中,似乎是因为 defaultvalue 初始化之间的差异取决于我如何定义我的类,初始化的结果可能会有所不同。例如,看看下面的类或http://coliru.stacked-crooked.com/a/b45acc5acf847e73

#include <iostream>
#include <string>
#include <vector>

class ClassWithDefaultedConstructor {
 public:
  ClassWithDefaultedConstructor() = default;
  int GetInt() const { return member_int_; }
  bool GetBool() const { return member_bool_; }
  std::string GetString() const { return member_string_; }

 private:
  int member_int_;
  bool member_bool_;
  std::string member_string_;
  int member_int_array_[5];
};

class ClassWithUserProvidedDefaultConstructor {
 public:
  ClassWithUserProvidedDefaultConstructor() : member_int_() {}
  int GetInt() const { return member_int_; }
  bool GetBool() const { return member_bool_; }
  std::string GetString() const { return member_string_; }

 private:
  int member_int_;
  bool member_bool_;
  std::string member_string_;
  int member_int_array_[5];
};

class ClassWithDefaultedConstructorAndDefaultMemberInitializers {
 public:
  ClassWithDefaultedConstructorAndDefaultMemberInitializers() = default;
  int GetInt() const { return member_int_; }
  bool GetBool() const { return member_bool_; }
  std::string GetString() const { return member_string_; }

 private:
  int member_int_{};
  bool member_bool_{};
  std::string member_string_;
  int member_int_array_[5]{};
};

int main()
{
    std::cout << "Hello World!" << std::endl;

    // Default initialization: int and bool members will have indeterminate values
    ClassWithDefaultedConstructor default_init1;
    // Value initialization: int and bool members will be zero-initialized
    ClassWithDefaultedConstructor value_init1{};

    // Default initialization: member_int_ is value initialized to 0 in constructor
    // member initiazer list but member_bool_ and member_int_array_ have indeterminate values
    ClassWithUserProvidedDefaultConstructor default_init2;
    // Value initialization: member_bool_ and member_int_array_ are default initialized
    // and have indeterminate values
    ClassWithUserProvidedDefaultConstructor value_init2{};

    // Default initialization: int and bool members are value initialized to 0 because
    // of the default member initializers value initializing them
    ClassWithDefaultedConstructorAndDefaultMemberInitializers default_init3;
    // Value initialization: same as if no default member initializers were used
    ClassWithDefaultedConstructorAndDefaultMemberInitializers value_init3{};
}

因此,根据我的类的客户端选择声明对象的方式(有或没有初始化程序),我的对象的起始状态会有所不同。这是真的?我在开源项目中遇到很多代码,其中标准库中的类类型成员(例如std::string)没有在用户提供的默认构造函数中初始化。如果是这样,我似乎应该为所有成员提供默认成员初始化程序,或者定义一个初始化所有成员的默认构造函数。默认构造函数和为所有成员使用默认成员初始化器与定义默认构造器初始化成员初始化器列表中的所有成员之间有什么区别吗?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    = default 导致您的成员默认初始化。

    对于内置类型,这什么都没有

    对于类类型,这是默认构造函数。

    如果你需要初始化一个东西,初始化它。如果你不这样做,不要。如果它是类类型成员(例如 std::string)并且默认构造就足够了,则您无需执行任何操作。

    【讨论】:

    • 对于struct C {int i; C() = default;};C c{}; 将执行值初始化并将i 初始化为零,C c; 将执行默认初始化并将保持i 未初始化。
    • 是的,但是使用= default,如果我初始化一个对象,它将首先被零初始化,这不会发生在用户提供的构造函数中。这就是我想要达到的行为差异。关于默认构造是否足够,我想这是我问题的症结所在。如果默认构造不够,会不会是一个设计错误的类?
    • @MikeSweeney,什么是“不足”?有时您希望在默认构造后保持成员未初始化。例如,我想为静态向量创建一个类并像这样使用它:MyVector&lt;10&gt; v; for (...) v[i] = ...;。这里我不希望构造函数用零初始化v,因为我以后会覆盖这些值。
    • @MikeSweeney,够用吗?对于某些操作(例如输入或赋值),处于部分形成状态就足够了。
    猜你喜欢
    • 2014-07-25
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多