当前位置:  开发笔记 > 编程语言 > 正文

确定方法是否为纯虚拟(c ++)

如何解决《确定方法是否为纯虚拟(c++)》经验,为你挑选了1个好方法。

有没有办法在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中执行它(特别是如果有许多派生类).

是否有便携和干净(没有标志)的方式来实现这个?...或者上述设计有什么问题?

编辑: - - - - - - - - - -

正如一些人所指出的那样,纯虚拟并不是真正的问题.它正在进入基类的析构函数,线程仍在运行.实际的问题可能是," 有没有办法在基类中使用预析构函数方法? "

In 是否有任何自动化方法来实现post-constructor和pre-destructor虚方法调用?Jeremy Friesner指出,有一个有趣的想法:

使基类和派生类的析构函数受到保护,因此无法调用delete.

使BaseClass的析构函数成为虚拟的.

在基类中实现Delete()首先终止线程,然后调用析构函数(调用虚拟派生析构函数)

Jeremy Fries.. 8

你在这里咆哮错误的树 - 在正确的C++程序中,不可能调用纯虚函数(因为调用它的尝试将被编译器标记为错误),因此无需确定在运行时,函数是否是纯虚函数.

有时你得到"纯虚函数调用"错误的原因是因为你的程序有问题 - 特别是它遇到了一个竞争条件,你的Run()方法正在调用一个正在处理的对象上的方法被摧毁.

你需要做的是确保线程已退出(通过要求线程退出,然后调用pthread_join()(或其他等效的API,将阻塞直到线程100%消失)销毁线程可能在运行时访问的任何对象之前.只有在线程死亡后才开始清理,这样就可以避免竞争条件,从而避免错误/崩溃.

请注意,将pthread_join()调用放在BaseClass的析构函数方法中是行不通的,因为在BaseClass析构函数运行时,对象的子类层已经被销毁.删除BaseClass为超类的对象之前,需要清理线程.(授予它在C++中自动执行该序列有点尴尬,因为AFAICT你必须确保调用者手动调用预删除线程关闭函数;特别是没有简单/自动/透明的方法来自动生成pre -destructor线程关闭代码)



1> Jeremy Fries..:

你在这里咆哮错误的树 - 在正确的C++程序中,不可能调用纯虚函数(因为调用它的尝试将被编译器标记为错误),因此无需确定在运行时,函数是否是纯虚函数.

有时你得到"纯虚函数调用"错误的原因是因为你的程序有问题 - 特别是它遇到了一个竞争条件,你的Run()方法正在调用一个正在处理的对象上的方法被摧毁.

你需要做的是确保线程已退出(通过要求线程退出,然后调用pthread_join()(或其他等效的API,将阻塞直到线程100%消失)销毁线程可能在运行时访问的任何对象之前.只有在线程死亡后才开始清理,这样就可以避免竞争条件,从而避免错误/崩溃.

请注意,将pthread_join()调用放在BaseClass的析构函数方法中是行不通的,因为在BaseClass析构函数运行时,对象的子类层已经被销毁.删除BaseClass为超类的对象之前,需要清理线程.(授予它在C++中自动执行该序列有点尴尬,因为AFAICT你必须确保调用者手动调用预删除线程关闭函数;特别是没有简单/自动/透明的方法来自动生成pre -destructor线程关闭代码)

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有