【C++】封装继承多态

简要回答

C++的三大特性就是:封装、继承、多态。 一句话概括就是:

封装:把数据和操作打包在一起,外人不能随便动,通过public,private,protected保护数据

继承:可以“复制+扩展”父类的内容,写代码更省力。

子类通过继承使用父类公开的数据,属性和方法,包括实现继承,接口继承和可视继承

多态:用“同一种方式”操作不同的对象,扩展性强。

详细回答

1.封装(Encapsulation)

封装是指把数据操作数据的方法包装在类里,通过**访问权限(public、private、protected)**来控制对外的暴露。

好处是提高安全性,把实现细节藏起来,别人只能用你提供的接口,而不能直接改内部数据

2继承(Inheritance)

继承让一个类(子类)拥有另一个类(父类)属性和行为,可以在原有功能的基础上做改进和拓展

有了继承,代码可以复用,比如定义一个Animal类,再派生出Dog、Cat等具体动物类,不用重复写代码。

3多态(Polymorphism)

多态指的是“同一种接口,不同的行为”。 主要有两种:

编译时多态(函数重载、运算符重载)运行时多态(虚函数+继承)

比如写了一个 speak() 接口,猫、狗调用它表现都不一样,这就是多态的威力。

其中编译时多态又叫静态多态,指的是在编译阶段就确定了函数调用的绑定关系

典型方式有两个:函数重载和运算符重载

运行时多态又叫动态多态,指的是在程序运行时根据对象的实际类型来决定调用哪个函数

原理是通过重写父类虚函数,生成虚函数表和虚函数指针,通过父类引用指向不同的子类对象选取不同的虚函数表进而实现多态。

代码示例

#include <iostream>
using namespace std;

// 封装
class Animal {
protected:
    string name;
public:
    Animal(string n) : name(n) {}
    virtual void speak() {  // 多态:虚函数
        cout << name << " is making a sound." << endl;
    }
};

// 继承
class Dog : public Animal {
public:
    Dog(string n) : Animal(n) {}
    void speak() override {  // 重写父类方法,实现运行时多态
        cout << name << " says: Woof!" << endl;
    }
};

class Cat : public Animal {
public:
    Cat(string n) : Animal(n) {}
    void speak() override {
        cout << name << " says: Meow!" << endl;
    }
};

// 多态的体现
void animalSpeak(Animal* a) {
    a->speak();  // 根据对象的真实类型调用不同的方法
}

int main() {
    Dog d("Buddy");
    Cat c("Kitty");

    animalSpeak(&d);  // 输出:Buddy says: Woof!
    animalSpeak(&c);  // 输出:Kitty says: Meow!
    return 0;
}

知识拓展

  • 知识图解

  • 面试官可能追问

编译时多态可以代替运行时多态吗?

答: 不完全可以。

编译时多态(如模板、函数重载)是在编译期确定函数调用,适用于参数类型、数量已知的情况。

而运行时多态(虚函数+继承)则是运行时根据对象真实类型做动态绑定,适用于“需要统一接口处理不同对象”的情况。

当对象的真实类型在编译时就能确定,并且想避免虚函数开销,可以用模板+策略模式模拟运行时多态效果。

虚函数调用的底层机制是怎样的?vtable 和 vptr 是怎么工作的?

答:虚函数背后有三样东西:虚函数表,虚指针,动态绑定过程。

虚函数表(vtable): 每个含虚函数的类在编译时都会生成一个vtable,里面存的是该类的虚函数地址列表

虚指针(vptr): 每个对象内部都含一个隐藏的指针(vptr),指向它所属类的vtable

动态绑定过程: 如:当用Animal* a = new Dog()时: 创建Dog对象时,会设置a->vptr指向Dog类的vtable。

当调用a->speak(),程序会通过vptr找到Dog类的vtable,调用里边的speak()地址。

  • 拓展:

vtable 是类级别的(多个对象共享),vptr是对象级别

能不用虚函数实现运行时多态吗?

答:可以,但要用其他技巧,比如函数指针、策略模式、std::function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值