在初始化列表中使用“this”指针是否安全?

时间:2011-02-20 16:33:54

标签: c++ initialization this

我有两个有父子关系的类(Parent类有一个“Child类),而Child类有一个指向{{1}的指针1}}。在构造子节点时初始化父指针会很好,如下所示:

Parent

现在,我知道人们建议不要在初始化列表中使用class Child; class Parent; class Child { public: Child (Parent* parent_ptr_) : parent_ptr(parent_ptr_) {}; private: Parent* parent_ptr; }; class Parent { public: Parent() : child(this) {}; private: Child child; } C++ FAQ说我会收到编译器警告(BTW,在VS2010上,我没有收到警告),但我真的更喜欢这个,然后在this的构造函数中调用一些set函数。我的问题是:

  • 在创建Parent对象时是否明确定义了父this指针?
  • 如果是这样,为什么上面使用它会被认为是不好的做法?

谢谢,

波阿斯

编辑:感谢Timbo,它确实是duplicate(呵呵,我甚至选择了相同的类名)。所以让我们获得一些附加值:引用怎么样?是否可以/安全地执行以下操作? :

Child

3 个答案:

答案 0 :(得分:46)

是。只要没有用于直接或间接访问未初始化的成员或虚函数,就可以在初始化列表中使用this指针,因为该对象尚未完全构建。对象child可以存储this Parent指针以供日后使用!

答案 1 :(得分:10)

父“this指针,在”指针术语“中,定义良好的(否则父构造函数将如何知道它在哪个实例上运行?),但是:

  • Child对象之后声明的字段尚未初始化;
  • 构造函数中的代码尚未运行;
  • 另外,关于使用构造函数中的虚拟成员的常见警告应用 1

因此,父对象一般仍处于不一致状态;子对象在构造父对象时将做的所有事情都将在一个半构造的对象上完成,这通常不是一件好事(例如,如果它称为“正常”方法 - 依赖于以下事实:对象是完全构造的 - 你可能会进入“不可能”的代码路径。)

但是,如果所有子对象在其构造函数中都使用父指针来存储它以便稍后使用它(=>当它实际构造时),它没有任何问题。


  1. 即,虚拟分派在构造函数中不起作用,因为派生类构造函数尚未更新vtable。参见例如here

答案 2 :(得分:4)

只要你完全构造Parent对象之后的,就不会尝试取消引用指针,行为是明确定义的(正如@Sergey在下面的评论中所说的那样) ,如果正在构造的对象实际上是从Parent派生的,那么其构造函数的所有必须已经完成。)