使用基础和派生对象的虚函数

时间:2015-06-30 08:55:15

标签: c++ virtual object-slicing

我已阅读有关vtable的内容,并已理解指向基类和派生类对象的基类指针的概念。 有人可以解释当基类和派生类都是对象并且派生类对象被分配给基类对象时如何创建vtable的情况。以下示例中的案例3

#include <iostream>
#include <exception>
using namespace std;


class Base
{
public:
    virtual void function1() { cout<<"Base - func1"<<endl; }
    virtual void function2() { cout<<"Base - func2"<<endl; }
};

class Derived1: public Base
{
public:
    virtual void function1() { cout<<"Derived1 - func1"<<endl; }
};

class Derived2: public Base
{
public:
    virtual void function2() { cout<<"Derived2 - func2"<<endl; }
};

int main () 
{
    // Case 1
    Base* B1 = new Derived1();
    B1->function1();
    B1->function2();

    // Case 2
    cout<<endl;
    Base* B2 = new Derived2();
    B2->function1();
    B2->function2(); 

    // Case 3
    cout<<endl;
    Base B3;
    Derived1 D1;
    B3=D1;
    B3.function1();
    B3.function2(); 
}

输出:

Derived1 - func1
Base - func2

Base - func1
Derived2 - func2

Base - func1
Base - func2

2 个答案:

答案 0 :(得分:2)

B3=Derived;对象切片的示例 ...只分配了基类数据成员,并且vtable指针继续指向基类函数。

你应该避免切片 - 它可能很危险(请参阅this answer获得解释)。现在你知道了这个术语,你很容易找到关于物体切片的大量阅读....

答案 1 :(得分:0)

Base B3;
D1 Derived;
B3=Derived;  //There is called default assignment operator

它定义如下:

Base& operator=(const Base &objectToCopy) {...}

运算符采用类型为Base的参数,因此类型为D1的对象被视为类型为Base的对象。这意味着赋值运算符仅查看DerivedBase中的vtable字段。 但是,仍然不会复制指向foo.py(技术上是隐藏字段)的指针,因为它始终在构造函数中创建,并且它与实际对象类型永久关联。