When is it safe to call this-gt; in constructor and destructor(什么时候调用它是安全的-在构造函数和析构函数中)
问题描述
到目前为止,我还没有找到一个决定性的答案.什么时候从对象内部调用 this->
是安全的.尤其是在构造函数和析构函数内部.
I've not been able to find a conclusive answer to this so far. When is it safe to call this->
from within an object. And in particular from inside the constructor and destructor.
而且,当使用公共继承时.对 this 调用的结果使用 up 和 downcasting 是否安全?
And also, when using public inheritance. Is it safe to use up and downcasting on the result of the this call?
例如:
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
}
以上哪些情况是合法的?
Which of the above cases are legal?
注意:我知道上述许多做法都是不可取的.
Note: I'm aware a lot of the practices above are inadvisable.
推荐答案
在任何非静态成员函数中,this
指向调用该函数的对象.只要它是有效对象,就可以安全使用.
Within any non-static member function, this
points to the object that the function was called on. It's safe to use as long as that's a valid object.
在构造函数或析构函数的主体中,存在当前正在构造的类的有效对象.但是,如果这是某个派生类的基子对象,那么此时只有基子对象有效;所以向下转换并尝试访问派生类的成员通常是不安全的.出于同样的原因,在这里调用虚函数时需要小心,因为它们是根据被创建或销毁的类而不是最终覆盖程序来调度的.
Within the body of a constructor or destructor, there is a valid object of the class currently being constructed. However, if this is the base sub-object of some derived class, then only the base sub-object is valid at that time; so it's generally not safe to down-cast and try to access members of the derived class. For the same reason, you need to be careful calling virtual functions here, since they are dispatched according to the class being created or destroyed, not the final overrider.
在构造函数的初始化列表中,您只需要注意访问已初始化的成员;也就是说,在当前被初始化的成员之前声明的成员.
Within the initialiser list of a constructor, you'll need to be careful only to access members that have been initialised; that is, members declared before the one currently being initialised.
向上转换到基类总是安全的,因为基子对象总是首先被初始化.
Up-casting to a base class is always safe, since base sub-objects are always initialised first.
对于您刚刚添加到问题中的具体示例:
For the specific examples you just added to the question:
- case 1 没问题(如果脆弱的话),因为
a
在那个时候已经被初始化了.使用b
的值初始化a
将是未定义的,因为b
在a
之后初始化. - 情况 2 很好:此时所有成员都已初始化.
- case 3 不会编译,因为没有合适的
foo
构造函数.如果有,那么它将取决于构造函数对它做了什么——它是否在成员被初始化之前尝试访问它们. - 如果您添加了缺少的
)
,情况 4 将是格式良好的,但如果您尝试使用指针访问对象,则很危险.this
还没有指向一个有效的bar
对象(只有foo
部分已经被初始化)所以访问bar的成员代码> 可能会给出未定义的行为.简单地检查指针是否为非空就可以了,并且总是会给出
true
(无论您是否应用无意义的强制转换).
- case 1 is fine (if fragile), since
a
has been initialised at that point. Initialisinga
with the value ofb
would be undefined, sinceb
is initialised aftera
. - case 2 is fine: all members have been initialised at that point.
- case 3 won't compile, since there's no suitable
foo
constructor. If there were, then it would depend on what that constructor did with it - whether or not it tried to access members before they were initialised. - case 4 would be well-formed if you added the missing
)
, but dangerous if you tried to use the pointer to access the object.this
does not yet point to a validbar
object (only thefoo
part has been initialised) so accessing members ofbar
could give undefined behaviour. Simply checking whether the pointer is non-null is fine, and will always givetrue
(whether or not you apply a pointless cast).
这篇关于什么时候调用它是安全的->在构造函数和析构函数中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:什么时候调用它是安全的->在构造函数和析构函数中
基础教程推荐
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07