c++继承

本文探讨了C++中的两个重要概念:虚函数表(vtable)和对象切片(objectslicing)。通过示例代码详细解释了如何在继承体系中通过虚函数表实现多态,以及对象切片可能导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. vtable

在构造子类object的时候,首先调用基类构造函数,如果基类中有virtual function,那么基类构造函数会建一个虚函数表( vtable ) 。如果子类中override了基类中的函数,那么会用这个函数地址覆盖原来vtable中的entry。

这样在使用

SubClass *s = new SubClass();
BaseClass *base = s;

时,base->foo() 就可以调用到正确的子类中的函数(foo()在BaseClass中为virtual, 并被SubClass中的foo() override掉)。

2. object slicing

看下面的代码

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

class Pet {
public:
    int age_;
    Pet(int age): age_(age) {}
    virtual string getDescription() const {
        return "This is Pet class";
    }
};

class Dog : public Pet {
public:
    Dog(int age) : Pet(age) {}
    virtual string getDescription() const {
        return "This is Dog class";
    }
};

int main() {
    Dog d(2);
    Pet pet(0);

    pet = d;
    cout << pet.age_ << endl;  //should be 2

    Pet *pp = &d;
    cout<<pp->getDescription();  //should call func in Dog

    Pet p = d;
    cout << p.getDescription();  //should call func in Pet
    return 0;
}

当我们用Pet p = d,或传参时pass by value(instead of pass by reference)的时候,就会导致object slicing。因为copy constructor或operator=是这样的:

class MyClass {
     int x;
     char c;
     std::string s;
};
MyClass::MyClass(const MyClass& other) : x(other.x), c(other.c), s(other.s) {}

那么vtable会怎么变化呢?我猜,它会直接读p的vtable(复制构造函数直接构造出来的,而不是用s.vtable覆盖p.vtable,因为它不知道怎么对应地找)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值