使用虚拟继承时进行虚拟呼叫时遇到问题。
下面是示例可编译代码,演示了在不使用虚拟继承的情况下可以工作的代码,以及在使用虚拟继承时在运行时将失败的代码。
基本类别这是这两种情况的基本指标:
#include <iostream>
class Base
{
public:
Base() { }
virtual ~Base() { }
// we need to make this bad call a good one!
virtual void bad_call(void* ptr)
{
Base* pThis = static_cast<Base*>(ptr);
pThis->f();
}
protected:
virtual void f() { std::cout << x << std::endl; }
int x = 0;
};
class Midle1 :
virtual public Base
{
public:
Midle1() { }
~Midle1() override { }
};
class Midle2 :
virtual public Base
{
public:
Midle2() { }
~Midle2() override { }
};
案例1良好在这种情况下,bad_call
和good_call
虚拟函数都可以使用,而没有使用虚拟继承(只是普通继承):
class GoodDerived :
public Base
{
public:
GoodDerived()
{
}
~GoodDerived() override
{
}
void good_call(void* ptr)
{
GoodDerived* pThis = static_cast<GoodDerived*>(ptr);
pThis->f();
}
void f() override
{
++x;
std::cout << x << std::endl;
}
};
int main()
{
GoodDerived good_derived;
good_derived.good_call(&good_derived); // OK, will print 1
good_derived.bad_call(&good_derived); // OK, will print 2
std::cin.get();
return 0;
}
案例2错误在这种情况下,将利用虚拟继承,good_call
函数将成功,但bad_call
将因“访问冲突读取位置”而失败。
class BadDerived :
public Midle1,
public Midle2
{
public:
BadDerived() { }
~BadDerived() override { }
void good_call(void* ptr)
{
BadDerived* pThis = static_cast<BadDerived*>(ptr);
pThis->f();
}
void f() override
{
++x;
std::cout << x << std::endl;
}
};
int main()
{
BadDerived bad_derived;
bad_derived.good_call(&bad_derived); // OK, will print 1
bad_derived.bad_call(&bad_derived); // ERROR: causes access violation
std::cin.get();
return 0;
}
问题第二种情况是一个简单的代码,演示了我现在在项目中遇到的问题,我需要有关如何解决此问题的帮助,为什么虚拟继承会引起麻烦?
为什么第一种情况效果很好,而第二种效果不好?我正在使用msvc编译器顺便说一句。
拨打电话:
bad_derived.bad_call(static_cast<Base*>(&bad_derived));
您想指向对象的基础部分,但是使用虚拟继承时,不能保证将对象放置在何处。