问题描述
给定以下代码
class T {
public:
virtual ~T () {}
virtual void foo () = 0;
};
class U {
public:
U() {}
~U() {}
void bar () { std::cout << "bar" << std::endl; }
};
class A : public U, public T {
public:
void foo () { std::cout << "foo" << std::endl; }
};
int main () {
A * a = new A;
std::vector<U*> u;
std::vector<T*> t;
u.push_back(a);
t.push_back(reinterpret_cast<T*>(u[0]));
u[0]->bar ();
t[0]->foo ();
delete a;
return 0;
}
我得到我想要的输出
bar
foo
但是,如果我将 U
的定义更改为
However, if I change the definition of U
to
class U {
public:
U() {}
virtual ~U() {}
virtual void bar () { std::cout << "bar" << std::endl; }
};
我仍然编译正常,没有警告/错误,但输出现在
I still compile fine and without warnings/errors but the output is now
bar
bar
关于虚拟声明阻止我调用 foo
?
What is it about the virtual declaration that prevents me from calling into the foo
?
推荐答案
首先,在您的示例中没有虚拟基类。包含虚函数的类称为多态。 (在C ++中有虚拟基类这样的东西,但它与你的例子没有关系。)
Firstly, there are no virtual base classes in your example. Classes that contain virtual functions are called polymorphic. (There is such thing as "virtual base classes" in C++ but it has nothing to do with your example.)
其次,你的代码的行为不依赖任何虚拟声明。您通过使用 reinterpret_cast
故意销毁基本指针的完整性。因此,代码的行为是 undefined 。
Secondly, the behavior of your code does not depend on any virtual declarations. You have deliberately destroyed the integrity of the base pointer by using reinterpret_cast
. For this reason the behavior of the code is undefined.
从一个基指针直接转换到另一个在您的代码中)调用 cross-cast 。在C ++中可以执行交叉转换的唯一转型是 dynamic_cast
。
A direct cast from one base pointer to another (which is what you are trying to do in your code) is called cross-cast. The only cast in C++ that can carry out a cross-cast is dynamic_cast
.
t.push_back(dynamic_cast<T *>(u[0]));
您可以执行不带 dynamic_cast ,但是你必须使用
static_cast
来将指针下转到派生类型( A *
然后将其上变换到另一个基本指针类型
You can perform an indirect cross-cast without
dynamic_cast
, but for that you have to downcast the pointer to the derived type first (A *
) using static_cast
and then upconvert it to another base pointer type
t.push_back(static_cast<A *>(u[0])); // upconversion to `T *` is implicit
这篇关于继承自两个多态类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!