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

bav*_*aza 48 c++ initialization this

我有两个具有父子关系的Parent类(类"has-a" Child类),并且Child该类有一个指向它的指针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;
}
Run Code Online (Sandbox Code Playgroud)

现在,我认识的人建议不使用this在初始化列表,以及C++ FAQ说我会得到一个编译器警告(顺便说一句,在VS2010,我没有得到一个警告),但我真的很喜欢这更好,然后调用一些功能集在Parent的构造函数.我的问题是:

  • 在创建对象this时,父指针是否定义良好Child
  • 如果是这样,为什么如上所述使用它被认为是不好的做法?

谢谢,

波阿斯

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

class Child
{
public:
 Child (Parent& parnet_ptr_) : parent_ptr(parent_ptr_) {};

private:
 Parent* parent_ptr;
};

class Parent
{
public:
    Parent() : child(*this) {};

private:
    Child child;
}
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 49

是.只要它不被用于直接或间接访问未初始化的成员或虚函数,因为对象尚未完全构造,this在initial-list中使用指针是安全的.该对象可以存储指针供以后使用!childthisParent

  • 简而言之.孩子**不能**在其构造函数/析构函数中使用此指针,否则就可以了. (3认同)
  • 在父结构构建完成之前,在父级中调用虚函数也是不安全的. (2认同)

Mat*_*lia 12

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

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

因此,父对象通常仍处于不一致状态; 一切的子对象会做建筑的父对象上,将半构造的对象上进行,而这一般不是一个好东西(例如,如果它所谓的"正常"的方法 - 即依靠事实对象是完全构造的 - 您可能会进入"不可能"的代码路径).

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


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


Oli*_*rth 5

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