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
}
以上哪些案例是合法的
注意:我知道上面的许多做法都是不可取的在C++超级FAQ中有一个很好的条目: 有些人认为不应该在构造函数中使用this指针 因为这个物体还没有完全成形。但是你可以用这个 在构造函数中(在{body}中,甚至在初始化列表中) 如果你小心的话 这里有一些总是有效的东西:构造函数的{body}(或 从构造函数调用的函数)可以可靠地访问数据 在基类中声明的成员和/或在 构造函数自己的类。这是因为所有这些数据成员 保证在工程竣工时已全部施工完毕 构造函数的{body}开始执行 这里有一些永远不会工作的东西:构造函数的{body}(或 从构造函数调用的函数)无法深入到派生 通过调用在中重写的虚拟成员函数初始化 派生类。如果您的目标是在 派生类,您将无法获得所需的内容。请注意,您不会这样做 获取派生类中的重写,与调用方式无关 虚拟成员函数:显式使用this指针(例如。, this->method()),隐式使用this指针(例如method()), 甚至调用调用虚拟成员的其他函数 此对象上的函数。底线是:即使 调用方正在构造派生类的对象 基类的构造函数,您的对象尚未属于该派生类 班级。你已经被警告了 下面是一些有时有效的方法:如果您传递任何数据 必须将此对象中的成员转换为另一个数据成员的初始值设定项 确保其他数据成员已初始化。这个 好消息是,您可以确定其他数据成员是否 (或尚未)使用某种简单的语言初始化 独立于您正在使用的特定编译器的规则。 坏消息是,你必须知道这些语言规则(例如,base) 首先初始化类子对象(如果有,请查找顺序) 多个和/或虚拟继承!),然后在中定义数据成员 该类按照它们在列表中出现的顺序进行初始化 类声明)。如果你不知道这些规则,那就不要通过任何考试 来自此对象的数据成员(无论您是否 对任何其他数据成员的 初始化器!如果你知道规则,请小心
在任何非静态成员函数中,
此
指向调用该函数的对象。只要是有效对象,就可以安全使用
在构造函数或析构函数的主体中,存在当前正在构造的类的有效对象。但是,如果这是某个派生类的基子对象,则此时只有基子对象有效;因此,向下转换并尝试访问派生类的成员通常是不安全的。出于同样的原因,在这里调用虚拟函数时需要小心,因为它们是根据创建或销毁的类而不是最终重写器进行调度的
在构造函数的初始化器列表中,只需小心访问已初始化的成员;也就是说,在目前正在草签的成员之前宣布的成员
向上转换到基类总是安全的,因为基子对象总是先初始化
对于您刚才添加到问题中的具体示例:
- 案例1很好(如果易碎),因为
已在该点初始化。使用a
值初始化b
将是未定义的,因为a
是在b
之后初始化的a
- 案例2很好:所有成员都已在该点进行了草签
- 案例3不会编译,因为没有合适的
构造函数。如果有,那么这将取决于构造函数对它做了什么——在初始化成员之前,它是否尝试访问成员foo
- 如果您添加了缺少的
,则案例4的格式会很好,但如果您试图使用指针访问对象,则情况会很危险<代码>此尚未指向有效的)
对象(只有bar
部分已初始化),因此访问foo
的成员可能会产生未定义的行为。只需检查指针是否为非null就可以了,并且始终会给出bar
(无论是否应用无意义转换)true
this
是一个prvalue表达式,其值为调用函数的对象的地址。类X的成员函数中的类型是X*。如果成员函数声明为const,则其类型为const X*;如果成员函数声明为volatile,则其类型为volatile X*;如果成员函数声明为const volatile,则其类型为const volatile X*
... 其中构造函数和析构函数是成员函数。。。
§12/1<