确定一个方法是否是纯虚拟的(c++)
Determine if a method is pure virtual (c++)
有没有办法在c++中确定一个方法在运行时是否是纯虚拟的?事实上,问题是是否有办法知道派生类的析构函数是否已经执行,但基类仍然存在。
这是我的案例(简化):
class BaseClass{
private:
class ThreadUtil *threadUtil;
public:
Mutex mutex;
~BaseClass(){
threadUtil->Terminate();
MutexLocker ml(mutex); // Avoid destruction during use
}
virtual Size size()=0;
};
class Derived:public BaseClass{
public:
Size size()override{return Size(100,80);}
};
class ThreadUtil{
private:
bool terminate;
BaseClass *owner;
public:
void Run(){
while(!terminate){
if (!IS_OWNER_SIZE_FN_PURE_THAT_S_THE_QUESTION){
MutexLocker ml(owner->mutex);
DoSomething(owner->size()); // Runtime error if in the dtor of BaseClass
}
}
}
};
"称为"的纯虚拟函数运行时错误偶尔发生(当在执行~BaseClass时调用DoSomething时)。
在派生类中终止线程+锁定是安全的,但我希望在BaseClass中这样做(尤其是在有许多派生类的情况下)。
有没有一种便携、干净(周围没有标志)的方法来实现这一点?。。。或者上面的设计出了什么问题?
编辑:----------------------
正如一些人所指出的,纯粹的虚拟并不是真正的问题。它正在进入基类的析构函数,而线程仍在运行。实际的问题可能是,"有没有办法在基类中使用预析构函数方法?">
在中,是否有任何自动化的方法来实现后构造函数和预析构函数虚拟方法调用?Jeremy Friesner指出,有一个有趣的想法:
- 使基类和派生类的析构函数受到保护,因此不能调用delete
- 使基类的析构函数成为虚拟的
- 在基类Delete()中实现,它首先终止线程,然后调用析构函数(调用虚拟派生的析构函数)
你在这里找错了树——在一个正确的C++程序中,不可能调用纯虚拟函数(因为试图调用它会被编译器标记为错误),所以不需要在运行时确定函数是否是纯虚拟的。
有时你会得到"纯虚拟函数调用"错误的原因是你的程序有缺陷——特别是,它受到竞争条件的影响,你的Run()方法正在调用一个正在被销毁的对象上的方法。
这里需要做的是确保线程已经退出(通过要求线程退出,然后调用pthread_join(或其他类似的API,它将阻塞,直到线程100%退出),然后销毁线程在运行时可能访问的任何对象。只有在线程死后才开始清理,这样就可以避免竞争条件,从而避免错误/崩溃。
请注意,将pthread_join()调用放在BaseClass的析构函数方法中是不起作用的,因为当BaseClass析构函数运行时,对象的子类层已经被破坏。在删除BaseClass是其超类的对象之前,您需要清理线程。(当然,在C++中自动执行该序列有点尴尬,因为AFAICT必须确保调用方手动调用预删除线程关闭函数;特别是没有简单/自动/透明的方法来自动生成预销毁线程关闭代码)
是否有一种可移植且干净(周围没有标志)的方法来实现这一点?。。。或者上面的设计出了什么问题?
可移植且干净的方法是在线程终止之前防止对象被破坏。这可以通过类TheradUtil通过适当类型的智能指针来拥有或共享BaseClass
的所有权来实现。
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- std::is_trivially_copyable_v 关于虚拟功能
- 删除C++继承中虚拟类成员的代码重复
- 子类地址等于虚拟基类地址?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?