Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual c++ c++;:“崩溃说”;纯虚拟称为;_Visual C++ - Fatal编程技术网

Visual c++ c++;:“崩溃说”;纯虚拟称为;

Visual c++ c++;:“崩溃说”;纯虚拟称为;,visual-c++,Visual C++,{使用Visual Studio 2010,Win7} class Base { public: Base() : terminateCondition(false) { //spawn new thread and set entry point to newThreadFunc() } virtual ~Base() // edited to say it's virtual.

{使用Visual Studio 2010,Win7}

class Base
{
    public:
        Base() : terminateCondition(false)
        {
            //spawn new thread and set entry point to newThreadFunc()
        }

        virtual ~Base() // edited to say it's virtual.
        {
            terminateCondition=true;
            //wait for thread to join
        }

        virtual void vfunc() = 0;

        static void __stdcall newThreadFunc(void *args)
        {
            while(!terminateCondition)
                pThis->vfunc();
        }

        volatile bool terminateCondition;
};

class Derived : public Base
{
    public:
        virtual void vfunc()
        {
            //Do Something
        }
};

Derived* dPtr=new Derived; //now assume pThis is dptr
//later somewhere
delete dPtr;

此代码崩溃,称为
纯虚拟调用
。将
terminateCondition=true
移动到
Derived
的析构函数可防止此崩溃。我想我部分了解原因。销毁与构造的顺序相反,因此首先执行
派生的
的任务,并在调用
基本的
任务之前销毁
派生的
的所有功能。同时,如果遇到
pThis->vfunc()
,应用程序将崩溃。它称为纯虚拟。我不明白这部分。有人能解释一下吗?

您的基类析构函数需要是
虚拟的
,因为它不是此代码调用的未定义行为

参考资料:
C++03标准:第5.3.5/3节:

如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,且静态类型应具有虚拟析构函数或行为未定义


当您通过构造函数/析构函数调用虚拟函数时,动态分派不会像您期望的那样工作。
构造函数/析构函数中的
this
的类型与正在执行构造函数/析构函数的类的类型相同。虽然您希望动态分派调用覆盖的派生类方法
derived::vfunc()
,但它最终会调用
Base::vfunc()
,该方法没有定义,因此会导致未定义的行为

参考资料:
C++03标准10.4/6:

“成员函数可以从抽象类的构造函数(或析构函数)调用;直接或间接地对纯虚拟函数进行虚拟调用(10.3)对从此类构造函数(或析构函数)创建(或销毁)的对象的影响尚未定义。”


您的基类析构函数需要是
虚拟的
,因为它不是此代码调用的未定义的行为

参考资料:
C++03标准:第5.3.5/3节:

如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,且静态类型应具有虚拟析构函数或行为未定义


当您通过构造函数/析构函数调用虚拟函数时,动态分派不会像您期望的那样工作。
构造函数/析构函数中的
this
的类型与正在执行构造函数/析构函数的类的类型相同。虽然您希望动态分派调用覆盖的派生类方法
derived::vfunc()
,但它最终会调用
Base::vfunc()
,该方法没有定义,因此会导致未定义的行为

参考资料:
C++03标准10.4/6:

“成员函数可以从抽象类的构造函数(或析构函数)调用;直接或间接地对纯虚拟函数进行虚拟调用(10.3)对从此类构造函数(或析构函数)创建(或销毁)的对象的影响尚未定义。”


这是因为在代码中,当
Base::Base()
尚未完成或
Base::~Base()
已启动时,可以调用
vfunc
。这两种情况都将调用未定义的行为,通常表现为“纯虚拟调用”错误。 这是一个错误的原因是“虚拟”机制直到大多数派生对象的类的构造函数开始运行后才生效,而“虚拟”机制在大多数派生对象的类的析构函数完成运行后不再有效。因此,当在对象上执行构造函数或析构函数时调用虚函数时,将调用构造函数或析构函数所执行的类的相应函数。如果该函数恰好是纯虚函数,则行为是未定义的

ISO/IEC 14882:2003,10.4/6: 成员函数可以从抽象类的构造函数(或析构函数)调用;制作的效果 直接或间接为正在创建的对象对纯虚拟函数的虚拟调用(10.3)(或
未定义此类构造函数(或析构函数)中的

这是因为在代码中,
vfunc
可以在
Base::Base()
尚未完成或
Base::~Base()
已启动时调用。这两种情况都将调用未定义的行为,通常表现为“纯虚拟调用”错误。 这是一个错误的原因是“虚拟”机制直到大多数派生对象的类的构造函数开始运行后才生效,而“虚拟”机制在大多数派生对象的类的析构函数完成运行后不再有效。因此,当在对象上执行构造函数或析构函数时调用虚函数时,将调用构造函数或析构函数所执行的类的相应函数。如果该函数恰好是纯虚函数,则行为是未定义的

ISO/IEC 14882:2003,10.4/6: 成员函数可以从抽象类的构造函数(或析构函数)调用;制作的效果 直接或间接为正在创建的对象对纯虚拟函数的虚拟调用(10.3)(或
来自这样一个构造函数(或析构函数)的(已销毁)是未定义的。

这将帮助您。。请注意,不要对线程之间共享的数据使用
volatile
。在这里使用原子数据类型。@mhasan:谢谢,我会看的it@usta:哦,好的。你能给我一个提示吗。我没有完全理解你。这里的volatile有什么问题吗?例如,看看这里:T