通过"this"指向析构函数中其他类/函数的指针 [英] Passing the "this" pointer to other class/function in destructor
问题描述
在某些主对象的析构函数中的堆栈上创建一个工作对象并将主对象的 this
指针传递给帮助对象,这是合法的C ++吗?然后,辅助对象还将调用主对象的成员函数或访问成员变量.
Is it legal C++ to create a worker-object on the stack in the destructor of some master-object and pass the this
pointer of the master-object to the helper-object? The helper-object would then also call member functions of the master-object or access member-variables.
换句话说,下面的合法C ++吗?
In other words, is the following legal C++?
struct MasterClass
{
MasterClass (int data);
~MasterClass ();
int data;
};
struct WorkerClass
{
WorkerClass (MasterClass *m) : m (m) { }
void do_some_work () { m->data = 42; }
MasterClass *m;
};
MasterClass::MasterClass (int data)
: data (data)
{ }
MasterClass::~MasterClass ()
{
WorkerClass w (this);
w.do_some_work ();
}
int main ()
{
MasterClass m (7);
}
我知道一旦析构函数开始执行,主对象的生命周期就会结束.但是我相信在任何对象的析构函数中调用非虚拟成员函数都是合法的,该函数使用隐式 this
参数/参数.
I understand that the lifetime of the master-object ends once the destructor begins to execute. But I believe it is legal to call non-virtual member functions in the destructor of any object, which make use of the implicit this
argument/parameter.
推荐答案
是,不是.
是的,因为在您展示的这个非常简短的示例中它是合法的.
Yes, because its legal in this very short example you've shown.
否,因为它可能会导致UB,所以在销毁过程中围绕对象的使用存在一些警告
No, because it might result in UB, there are some caveats surrounding usage of an object during destruction
TLDR如果您没有任何继承,那总是很好.
TLDR It's always fine if you don't have any inheritance.
现在,对于在销毁期间使用对象不的情况.
Now, for the cases where it is not fine to use an object during destruction.
在以下情况下,将假定已编写以下内容
The following cases will assume the following is already written
struct V;
struct A;
struct B;
struct D;
void foo(A* a = nullptr);
struct V {
virtual void f();
virtual void g();
};
struct A : virtual V {
virtual void f();
};
struct B : virtual V {
virtual void g();
~B() {
foo();
}
};
struct D : A, B {
virtual void f();
virtual void g();
~D() {
foo(this);
}
};
int main() {
D d;
}
调用虚函数
在销毁 x
时(也就是它的析构函数被调用时)
Calling virtual functions
Upon the destruction of x
(aka as soon as its destructor is called)
如果虚拟函数调用使用显式类成员访问,并且对象表达式引用
x
的完整对象或该对象的基类子对象之一,但不引用x
或其基类子对象之一,其行为是不确定的.
If the virtual function call uses an explicit class member access and the object expression refers to the complete object of
x
or one of that object's base class subobjects but notx
or one of its base class subobjects, the behavior is undefined.
这意味着,如果您使用显式类成员访问来使用指向整个 x
的指针来调用虚拟函数,但是某种程度上该指针不是 x的类型
或它的根据,行为是不确定的.
Which means, if you use a explicit class member access to call a virtual function with a pointer pointing to the entirety of x
, but somehow the pointer isn't the type of x
nor its bases, the behaviour is undefined.
void foo(A* a) {
static auto ptr = a;
ptr->g(); // UB when called from ~B
// ptr refers to B, but is neither B nor its base
}
使用 typeid
如果
typeid
的操作数是指正在构造或破坏的对象,并且该操作数的静态类型既不是构造函数或析构函数的类也不是其基础之一,则该行为是不确定的.>
If the operand of
typeid
refers to the object under construction or destruction and the static type of the operand is neither the constructor or destructor's class nor one of its bases, the behavior is undefined.
同样,如果操作数引用被破坏的对象,但由于某种原因不是对象及其基础,则行为是不确定的.
Likewise, if the operand refers to the object being destructed, yet somehow isn't the object and its bases, the behaviour is undefined.
void foo(A* a) {
static auto ptr = a;
typeid(*ptr); // UB when called from ~B()
// ptr refers to B, but is neither B nor its base
}
使用 dynamic_cast
如果
dynamic_cast
的操作数是指正在构造或破坏的对象,并且该操作数的静态类型不是指向构造函数或析构函数自己的类或其基础之一的指针或对象,则dynamic_cast
导致未定义的行为.
If the operand of the
dynamic_cast
refers to the object under construction or destruction and the static type of the operand is not a pointer to or object of the constructor or destructor's own class or one of its bases, thedynamic_cast
results in undefined behavior.
相同的交易.
void foo(A* a) {
static auto ptr = a;
dynamic_cast<B*>(ptr); // UB when called from ~B()
// ptr refers to B, but is neither B nor its base
}
结论
现在,如果您认为这是一场惨败并且不了解发生了什么,那就不要在析构函数中的任何地方传递 this
.
来自 http://eel.is/c++draft/的所有引号class.cdtor
这篇关于通过"this"指向析构函数中其他类/函数的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!