C ++多态性。这为什么有效?

时间:2014-11-21 05:19:51

标签: c++ visual-c++ gcc polymorphism vtable

这不应该是不正确的吗? :

A* apb = (A*)&b; //a pointer to b

我预计会出现错误,或至少是警告。

为什么在Visual C ++ 2013(v120)或g ++(gcc 4.8.2)中没有给我任何警告?

#ifndef A_H
#define A_H

#include <stdio.h>

class A
{
public:
   A(){}
   virtual ~A(){}
   void print(){ printf("printA\n"); }
   virtual void printVirtual(){ printf("printVirtualA\n"); }
};

#endif // A_H

#ifndef B_H
#define B_H

#include "A.hpp"
class B : A
{
public:
   B(){}
   void print(){ printf("printB\n"); }
   virtual void printVirtual(){ printf("printVirtualB\n"); }
};

#endif //B_H

int main()
{
   A a;
   B b;
   A* apb = (A*)&b; //a pointer to b
   B* bpa = (B*)&a; //b pointer to a

   apb->print();         // printA
   apb->printVirtual();  // printVirtualB
   bpa->print();         // printB
   bpa->printVirtual();  // printVirtualA
   return 0;
}

输出:

printA
printVirtualB
printB
printVirtualA

我怀疑是因为我的类在内存中对齐所以有一个有效的Vtable。

这是一个“隐含的”dynamic_cast吗?

据我所知,这样做不应该是正确的。

3 个答案:

答案 0 :(得分:1)

这正是vtable的用途。非虚函数被称为匹配容器的类型,虚函数被称为匹配指向对象的类型。

A* apb = (A*) &b;

....是完美的代码,是虚拟多态的典型例子。

答案 1 :(得分:0)

A* apb = (A*)&b;

从派生类初始化基类指针是完全可以的(假设b类型为B,如图所示。你甚至不需要施法操作

A* apb = &b;

void print()成员函数未标记为virtual,因此会在您手头的实际实例上调用成员函数。

答案 2 :(得分:0)

A* apb = (A*) &b;

这完全没问题。指向派生对象的基指针。此方案后面主要是抽象类(或接口)以启用多态