将“ this”指针传递给析构函数中的其他类/函数

托比·布鲁尔

在某些主对象的析构函数中的堆栈上创建一个工作对象并将主对象的this指针传递给帮助对象,这是合法的C ++吗?然后,辅助对象还将调用主对象的成员函数或访问成员变量。

换句话说,以下合法的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参数/参数。

适合者

是的,没有。

是的,因为在您展示的这个非常简短的示例中它是合法的。

不可以,因为它可能会导致UB,因此在销毁期间围绕对象的使用存在一些警告

TLDR如果您没有任何继承,那总是很好。

现在,对于在销毁期间不宜使用对象的情况。

以下情况将假定已编写以下内容

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(又称其析构函数)

如果虚拟函数调用使用显式类成员访问,并且对象表达式引用x该对象的基类子对象之一或其中一个的完整对象,但不引用x其基类子对象之一或其中的完整对象,则该行为是不确定的。

这意味着,如果您使用显式的类成员访问来调用指向整个的指针的虚函数x,但是某种程度上该指针既不是的类型x也不是其基数,则该行为是不确定的。

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

如果of的操作数是typeid指正在构造或破坏的对象,并且该操作数的静态类型既不是构造函数或析构函数的类也不是其基础之一,则该行为是不确定的。

同样,如果操作数引用被销毁的对象,但是某种程度上不是对象及其基础,则行为是不确定的。

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导致未定义的行为。

同样的交易。

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的所有引号

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章