c++ - 虚函数的意外行为?

标签 c++ visual-studio-2010 inheritance virtual

当我使用 Visual Studio 2010 运行以下 C++ 代码时,如果任何派生类函数被声明为虚函数,程序就会卡在变量删除处。谁能解释一下?

void testInheritance()
{
    class a
    {
        public :
            char x;
            void fn1()
            {
                std::cout<<"\n In Class A Function 1 : "<<x;
            }
            virtual void fn2()
            {
                std::cout<<"\n In Class A Function 2 : "<<x;
            }
            a()
            {
                x='A';
                std::cout<<"\n In A() : "<<x;
            }
            ~a()
            {
                std::cout<<"\n In ~A : "<<x;
            }
    };

    class b: public a
    {
        public :
            char y;
            virtual void fn1()
            {
                std::cout<<"\n In Class B Function 1 : "<<y;
            }
             void fn3()
            {
                std::cout<<"\n In Class B Function 3 : "<<y;
            }
            b()
            {
                y='B';
                std::cout<<"\n In B() : "<<y;
            }
            ~b()
            {
                std::cout<<"\n In ~B : "<<y;
            }
    };

    a* var = new b();
    delete var;
}

更多信息:

我知道要调用 b::fn1 和类 b 的析构函数,我需要在基类(即类 a)中将它们声明为虚拟的。但是,如果我不这样做,甚至不将 b 类(也不是 a 类)中的任何函数声明为虚拟函数,它应该同时调用 fn1 和 a 的析构函数,这会完美地发生。但是,当我声明 b 的任何成员(但不是 a)是虚拟的,无论是新成员还是重载成员,然后它在用 VS2010 编译时挂起,在 linux 上用 gcc4.4.4 编译时中断。它应该调用其中一个析构函数并正常工作,但我无法理解程序中断的原因。

此外,在 Visual Studio 2010 中使用 Intellitrace 时,我尝试在它挂起的地方中断代码,我收到以下消息:

该进程似乎已死锁(或未运行任何用户模式代码)。所有线程都已停止。

最佳答案

您期望意外行为,因为您在您的程序中创建了一个未定义的行为

使用指向具有非虚析构函数类的指针删除派生类对象会导致未定义的行为。未定义的 Beahavor 意味着任何事情都可能发生。

C++ 标准第 1.3.24 节指出:

允许的未定义行为的范围包括从完全忽略具有不可预测结果的情况,到在翻译或程序执行期间以环境特征的文档化方式表现(有或没有发布诊断消息),到终止翻译或执行(发布诊断消息)。

如何解决问题?

基类中的析构函数应该是虚拟的。

关于c++ - 虚函数的意外行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6659691/

相关文章:

c++ - 使用 Objective-C++ 和 Objective-C 的链接器问题

调用函数时java子类状态不改变

c# - C#未运行派生类函数

c++ - 无法从类函数访问类变量

c++ - 在插入新键时保持 unordered_map 的顺序

c - Visual Studio : Unresolved external symbols after adding new DLL APIs

c++ - Visual Studio 2010 : Linker > Command Line contains unneeded . 库

c++ - 里面有if的宏?

c++ - 在 C++ 中覆盖具有不同返回类型的方法

c++ - 使用嵌入式脚本扩展 C++ 应用程序