什么时候不应该在构造函数中使用初始化列表?

时间:2012-04-25 21:02:00

标签: c++ constructor

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

我正在寻找以下声明的示例

  

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

2 个答案:

答案 0 :(得分:4)

我认为你的陈述的作者所指的主要概念是,初始化列表中对变量的调用按照你在初始化列表中看到的顺序发生,但是按照类定义中列出变量的顺序。

这意味着

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

我建议您看一下Scott Meyer的Effective C++,其中涵盖了这一点(在许多其他有用和信息丰富的主题中)。

答案 1 :(得分:2)

以下是一些例子:


  

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

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关键字   {开始构造函数的主体(当你的特定   编译器恰好发出特定的警告)。

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

此处,functor_在初始化/分配时需要使用this。如果我们在初始化列表中初始化functor_,则this指针将指向此时尚未完全初始化的对象。这可能是安全的,具体取决于具体情况,但是万无一失的选项是将functor_设置为直到构造函数体内,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_;
};

希望这是不言自明的。


我不确定是什么意思
  

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

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