C++ 何时可以安全地调用此->;在构造函数和析构函数中

C++ 何时可以安全地调用此->;在构造函数和析构函数中,c++,c++11,constructor,destructor,C++,C++11,Constructor,Destructor,到目前为止,我还没有找到一个决定性的答案。从对象中调用this->什么时候是安全的。特别是从构造函数和析构函数内部 而且,当使用公共继承时。对这次通话的结果使用上行和下行广播安全吗 例如: class foo { foo(): a(), b(this->a)//case 1 { this-> a = 5; //case 2 } int a; int b; }; class bar: public baz { bar()

到目前为止,我还没有找到一个决定性的答案。从对象中调用
this->
什么时候是安全的。特别是从构造函数和析构函数内部

而且,当使用公共继承时。对这次通话的结果使用上行和下行广播安全吗

例如:

class foo
{
   foo():
   a(),
   b(this->a)//case 1
   {
       this-> a = 5; //case 2
   }

   int a;
   int b;
};

class bar: public baz
{
   bar():
   baz(this)//case 3 - assuming baz has a valid constructor
   {


   }

}
最后是最不可能的一个

foo()
   {
      if(static_cast<bar*>(this));//case 4
   }
foo()
{
if(static_cast(this));//情况4
}
以上哪些案例是合法的


注意:我知道上面的许多做法都是不可取的

有些人认为不应该在构造函数中使用this指针 因为这个物体还没有完全成形。但是你可以用这个 在构造函数中(在{body}中,甚至在初始化列表中) 如果你小心的话

这里有一些总是有效的东西:构造函数的{body}(或 从构造函数调用的函数)可以可靠地访问数据 在基类中声明的成员和/或在 构造函数自己的类。这是因为所有这些数据成员 保证在工程竣工时已全部施工完毕 构造函数的{body}开始执行

这里有一些永远不会工作的东西:构造函数的{body}(或 从构造函数调用的函数)无法深入到派生 通过调用在中重写的虚拟成员函数初始化 派生类。如果您的目标是在 派生类,您将无法获得所需的内容。请注意,您不会这样做 获取派生类中的重写,与调用方式无关 虚拟成员函数:显式使用this指针(例如。, this->method()),隐式使用this指针(例如method()), 甚至调用调用虚拟成员的其他函数 此对象上的函数。底线是:即使 调用方正在构造派生类的对象 基类的构造函数,您的对象尚未属于该派生类 班级。你已经被警告了

下面是一些有时有效的方法:如果您传递任何数据 必须将此对象中的成员转换为另一个数据成员的初始值设定项 确保其他数据成员已初始化。这个 好消息是,您可以确定其他数据成员是否 (或尚未)使用某种简单的语言初始化 独立于您正在使用的特定编译器的规则。 坏消息是,你必须知道这些语言规则(例如,base) 首先初始化类子对象(如果有,请查找顺序) 多个和/或虚拟继承!),然后在中定义数据成员 该类按照它们在列表中出现的顺序进行初始化 类声明)。如果你不知道这些规则,那就不要通过任何考试 来自此对象的数据成员(无论您是否 对任何其他数据成员的 初始化器!如果你知道规则,请小心


在任何非静态成员函数中,
指向调用该函数的对象。只要是有效对象,就可以安全使用

在构造函数或析构函数的主体中,存在当前正在构造的类的有效对象。但是,如果这是某个派生类的基子对象,则此时只有基子对象有效;因此,向下转换并尝试访问派生类的成员通常是不安全的。出于同样的原因,在这里调用虚拟函数时需要小心,因为它们是根据创建或销毁的类而不是最终重写器进行调度的

在构造函数的初始化器列表中,只需小心访问已初始化的成员;也就是说,在目前正在草签的成员之前宣布的成员

向上转换到基类总是安全的,因为基子对象总是先初始化

对于您刚才添加到问题中的具体示例:

  • 案例1很好(如果易碎),因为
    a
    已在该点初始化。使用
    b
    值初始化
    a
    将是未定义的,因为
    b
    是在
    a
    之后初始化的
  • 案例2很好:所有成员都已在该点进行了草签
  • 案例3不会编译,因为没有合适的
    foo
    构造函数。如果有,那么这将取决于构造函数对它做了什么——在初始化成员之前,它是否尝试访问成员
  • 如果您添加了缺少的
    ,则案例4的格式会很好,但如果您试图使用指针访问对象,则情况会很危险<代码>此尚未指向有效的
    bar
    对象(只有
    foo
    部分已初始化),因此访问
    bar
    的成员可能会产生未定义的行为。只需检查指针是否为非null就可以了,并且始终会给出
    true
    (无论是否应用无意义转换)
在每个非静态成员函数中都可以访问此指针。。。 §9.3.2/1

在非静态(9.3)成员函数体中,关键字
this
是一个prvalue表达式,其值为调用函数的对象的地址。类X的成员函数中的类型是X*。如果成员函数声明为const,则其类型为const X*;如果成员函数声明为volatile,则其类型为volatile X*;如果成员函数声明为const volatile,则其类型为const volatile X*

... 其中构造函数和析构函数是成员函数。。。 §12/1<