损坏的虚拟表视觉工作室错误

时间:2016-05-04 15:55:55

标签: c++ visual-studio visual-studio-2010 visual-studio-2012 visual-studio-2015

我遇到了一些在我看来是一个损坏的虚拟表,它是由构建和运行Visual Studio 2015中下面发布的示例代码而产生的。

当我运行它时,在分配m_string时抛出异常。

我已经验证了代码使用gcc和Clang编译器构建并按预期运行。

我试图让这个例子尽可能小,因为它是从一个非常大的项目中合成的。

另外,我意识到我从某些函数返回null - 实际返回值与问题无关,但返回类型可能是。这可能是Visual Studio的错误吗?

#include <iostream>
#include <memory>
#include <string>

struct A { virtual ~A(void) { } };
struct B { virtual ~B(void) { } };
struct C : public A, public B { virtual ~C(void) override { } };

struct D
{
    virtual ~D(void) { }
    virtual B *func(void) = 0;
};

struct E : public D
{
    virtual ~E(void) override { }
    virtual C *func(void) override { return nullptr; }
};

struct F : public A, public E
{
    virtual ~F(void) override { }
    C *func(void) override
    {
        m_string = "Why does the act of setting this field cause a crash?";

        return nullptr;
    }

    std::string m_string;
};

int main(int argc, char **argv)
{
    std::unique_ptr<F> pF(new F());
    (dynamic_cast<D *>(pF.get()))->func();
    pF->func();

    return 0;
}

1 个答案:

答案 0 :(得分:2)

解决方案是从A类虚拟继承。

struct C : virtual public A, public B { virtual ~C(void) override { } };

struct F : virtual public A, public E { ... }

问题很可能与基类中的虚拟析构函数有关。也许其他人可以提供更多解释为什么这样做。

正如@JamesAdkison指出的那样,交换继承的类(将struct C : public A, public B {...}更改为struct C : public B, public A {...})也可以解决问题;将struct F : public A, public E { ... }更改为struct F : public E, public A { ... }也是如此。所以,它似乎是MSVC中的一个错误,正如@Josh P。

所提到的那样