4

当我们不应该在构造函数中使用初始化列表时,有人可以引用一个示例代码,以及如何通过赋值来克服它?

我正在寻找以下语句的示例

当您的类有两个需要以this不同顺序初始化对象的数据成员的构造函数时,可能会发生这种情况。或者,当两个数据成员是自引用的时,它可能会发生。或者当数据成员需要对 this 对象的引用,并且您希望避免编译器警告在开始构造函数主体的 { 之前使用 this 关键字(当您的特定编译器恰好发出该特定警告时)。或者当您需要在使用该变量初始化您的 this 成员之一之前对变量(参数、全局等)进行 if/throw 测试时。

4

2 回答 2

4

我相信您的陈述作者所指的主要概念是,对初始化列表中的变量的调用不是按照您在初始化列表中看到它们的顺序发生的,而是按照变量在中列出的顺序发生的定义

这意味着

  • 如果您有两个使用初始化列表的不同构造函数,它们必须以相同的顺序初始化它们
  • 您对排序的控制(如果您有相互依赖的成员,这可能很重要)是有限的

我建议您看一下Effective C++涵盖此内容的 Scott Meyer(在许多其他有用且信息丰富的主题中)。

于 2012-04-25T21:07:21.377 回答
2

这里有些例子:


当您的类有两个需要以不同顺序初始化 this 对象的数据成员的构造函数时,可能会发生这种情况。

class Example1 {
 public:
  Example1(std::string decoded, std::string encoded)
      : decoded_(decoded),
        encoded_(encoded) {}
  explicit Example1(std::string encoded)
      : decoded_(),  // Can't use "decoded_(Decode())" since "encoded_" isn't initialised
        encoded_(encoded) {
    decoded_ = Decode();  // Assign here instead of initialising
  }
 private:
  std::string Decode();  // decodes class member "encoded_"
  std::string decoded_, encoded_;
};

在此示例中,decoded_将始终在之前初始化,encoded_因为这是它们在类中声明的顺序,即使我们在初始化列表中交换它们的顺序。


或者当数据成员需要对 this 对象的引用,并且您希望避免在开始构造函数主体的 { 之前使用 this 关键字的编译器警告(当您的特定编译器恰好发出该特定警告时)。

class Example2 {
 public:
  Example2() : functor_() {
    functor_ = std::bind(&Example2::Do, this);
  }
 private:
  void Do();
  std::function<void()> functor_;
};

在这里,functor_需要在this初始化/分配时使用。如果我们要functor_在初始化列表中进行初始化,则this指针将指向一个当时尚未完全初始化的对象。根据特定情况,这可能是安全的,但万无一失的选项是将设置推迟functor_到构造函数主体内部,此时this 确实引用了完全初始化的对象。


或者当您需要在使用该变量初始化您的 this 成员之一之前对变量(参数、全局等)进行 if/throw 测试时。

class Example3 {
 public:
  Example3(int force, int acceleration)
      : force_(force),
        acceleration_(acceleration),
        mass_(0) {
    if (acceleration_ == 0)
      throw std::exception("Can't divide by 0");
    mass_ = force_ / acceleration_;
  }
 private:
  int force_, acceleration_, mass_;
};

希望这是不言自明的。


我不确定是什么意思

当两个数据成员是自引用的

所以恐怕我不能举一个例子。

于 2012-04-25T22:32:00.803 回答