gpt4 book ai didi

c++ - 在销毁派生成员之前在析构函数中调用公共(public)函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:02:21 28 4
gpt4 key购买 nike

假设我们有这样的经典基类和派生类

class B {
public:
virtual ~B() {
// calling it here is too late, see explanations
//common_pre_cleanup_function();
}

void common_pre_cleanup_function() { }
};

class D : public B {
public:
virtual ~D() {
// What if we forget to do this call in another derived class?
common_pre_cleanup_function();
}
};

D 的成员被销毁之前,您如何确保在所有派生的 D 的析构函数中调用像 common_pre_cleanup_function() 这样的函数但不必在新 D 的每个析构函数实现中显式调用此函数?

背景

在我当前的项目中,我们有一个基类,它实现了某些并行性和线程特性,并最终将启动一个新线程来完成实际工作。在这个基类的析构函数中,我们想确保线程总是被停止和连接,以便它得到正确的清理。

然而,派生类可以创建由基类中的线程使用的成员。所以如果我们销毁派生类的对象,这些成员也会被销毁。但是此时由基类管理的线程仍然可以运行并且现在错误地访问被销毁的成员。

我知道这不是解决问题的最明智的方法,可能将线程/并行化部分和“实际工作”部分分成单独的类可能是更聪明的想法。但是,如果有任何方法不涉及对现有代码库的整个重写,我很感兴趣。

这里的这段代码比较接近我们的情况

class BackgroundTask {
public:
virtual ~BackgroundTask() {
// if we forget to call stop() in the derived classes, we will
// at this point have already destroyed any derived members
// while the thread might still run and access them; so how/where
// can we put this call?
//stop();
}

void stop() {
cancelFlag_.set();
thread_.join();
}

// more functions helping with Background tasks

private:
Thread thread_;
Condition cancelFlag_;
};

class MyTask : public BackgroundTask {
public:
virtual ~MyTask() {
// with the current case, we have to remember to call
// this function in all destructors in classes derived
// from BackgroundTask; that's what I want to avoid
stop();
}

private:
std::unique_ptr<MyClass> member;
};

最佳答案

很简单,你不知道。在这种情况下,最好的办法是重新设计一切的工作方式,以防止这成为一个问题。

但让我们面对现实吧,您很可能没有时间和/或资源来实现这一目标。因此,您的第二个最佳选择(在我看来)是确保对派生类的已销毁成员的任何调用都会立即终止您的应用程序,并显示一条非常明确的错误消息。

如果系统必须失败,尽早失败。

关于c++ - 在销毁派生成员之前在析构函数中调用公共(public)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57289371/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com