C++面试宝典&八股文之"什么是封装、继承、多态"(附面试宝典&八股文PDF)

一、C++面试宝典&八股文

PDF文档自取:https://pan.quark.cn/s/5d4c5050d512
二、什么是封装、继承、多态?

1.封装

概念:

封装是将数据(属性)和操作数据的方法(行为)捆绑在一起,形成一个独立的单元(即类),并尽可能隐藏类的内部实现细节,只保留有限的接口与外部交互。

目的:

保护数据不被外部直接访问喝修改

提高代码的可维护性和安全性

降低模块间的耦合度

实现方式:

private、protected、public

提供公共的getter和setter方法访问私有成员

代码案例:

复制代码
#include <iostream>#include <string>
class BankAccount {private:
    std::string accountNumber;
    double balance;
    public:
    // 构造函数
    BankAccount(const std::string& accNum, double initialBalance)
        : accountNumber(accNum), balance(initialBalance) {}
    
    // 公共接口方法
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            std::cout << "Deposited: $" << amount << std::endl;
        }
    }
    
    bool withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
            std::cout << "Withdrew: $" << amount << std::endl;
            return true;
        }
        std::cout << "Insufficient funds or invalid amount" << std::endl;
        return false;
    }
    
    double getBalance() const {
        return balance;
    }
    
    std::string getAccountNumber() const {
        return accountNumber;
    }
};
int main() {
    BankAccount account("123456789", 1000.0);
    
    account.deposit(500);
    account.withdraw(200);
    
    // 尝试直接访问私有成员会导致编译错误
    // account.balance = 1000000; // 错误!
    
    std::cout << "Account: " << account.getAccountNumber() 
              << ", Balance: $" << account.getBalance() << std::endl;
    
    return 0;
}

2.继承

概念:

继承允许一个类(派生类/子类)基于另一个类(基类/父类),从而可以重用基类的属性和方法,并可以添加新的功能或修改现有功能。

类型:

单继承:一个子类只有一个父类

多继承:一个子类有多个父类(C++特有)

访问修饰符:

public:基类的public成员在派生类中保持public,protected保持protected

protected:基类的public和protected成员在派生类中都变为protected

private:基类的public和protected成员在派生类中都变为private

代码案例:

复制代码
#include <iostream>#include <string>
// 基类class Animal {protected:
    std::string name;
    int age;
    public:
    Animal(const std::string& name, int age) : name(name), age(age) {}
    
    void eat() {
        std::cout << name << " is eating." << std::endl;
    }
    
    void sleep() {
        std::cout << name << " is sleeping." << std::endl;
    }
    
    virtual void makeSound() {
        std::cout << "Some generic animal sound" << std::endl;
    }
};
// 派生类class Dog : public Animal {private:
    std::string breed;
    public:
    Dog(const std::string& name, int age, const std::string& breed)
        : Animal(name, age), breed(breed) {}
    
    void fetch() {
        std::cout << name << " is fetching the ball." << std::endl;
    }
    
    // 重写基类方法
    void makeSound() override {
        std::cout << name << " says: Woof! Woof!" << std::endl;
    }
    
    void displayInfo() {
        std::cout << "Dog: " << name << ", Age: " << age 
                  << ", Breed: " << breed << std::endl;
    }
};
// 另一个派生类class Cat : public Animal {public:
    Cat(const std::string& name, int age) : Animal(name, age) {}
    
    void purr() {
        std::cout << name << " is purring." << std::endl;
    }
    
    // 重写基类方法
    void makeSound() override {
        std::cout << name << " says: Meow!" << std::endl;
    }
};
int main() {
    Dog myDog("Buddy", 3, "Golden Retriever");
    Cat myCat("Whiskers", 5);
    
    myDog.displayInfo();
    myDog.eat();      // 继承自Animal
    myDog.sleep();    // 继承自Animal
    myDog.fetch();    // Dog特有方法
    myDog.makeSound(); // 重写的方法
    
    std::cout << std::endl;
    
    myCat.makeSound(); // 重写的方法
    myCat.purr();     // Cat特有方法
    myCat.sleep();    // 继承自Animal
    
    return 0;
}

3.多态

概念:

多态允许使用统一的接口来处理不同类型的对象,同一操作作用于不同类的对象时可以有不同的解释和执行方式。

分类:

编译时多态(静态多态):通过函数重载和模板实现

运行时多态(动态多态):通过虚函数和继承实现

注意:

基类指针或引用指向派生类对象

基类中声明虚函数(virtual)

派生类中重写虚函数(通常使用override关键字)

代码案例:

复制代码
#include <iostream>#include <vector>#include <memory> // 用于智能指针
// 基类class Shape {public:
    // 虚函数
    virtual double area() const {
        return 0.0;
    }
    
    // 纯虚函数 - 使Shape成为抽象类
    virtual void draw() const = 0;
    
    // 虚析构函数 - 确保派生类对象被正确销毁
    virtual ~Shape() {}
};
// 派生类1class Circle : public Shape {private:
    double radius;
    public:
    Circle(double r) : radius(r) {}
    
    double area() const override {
        return 3.14159 * radius * radius;
    }
    
    void draw() const override {
        std::cout << "Drawing a circle with radius " << radius << std::endl;
    }
};
// 派生类2class Rectangle : public Shape {private:
    double width, height;
    public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    double area() const override {
        return width * height;
    }
    
    void draw() const override {
        std::cout << "Drawing a rectangle " << width << "x" << height << std::endl;
    }
};
// 编译时多态示例(函数重载)class Print {public:
    static void display(int i) {
        std::cout << "Integer: " << i << std::endl;
    }
    
    static void display(double d) {
        std::cout << "Double: " << d << std::endl;
    }
    
    static void display(const std::string& s) {
        std::cout << "String: " << s << std::endl;
    }
};
int main() {
    // 运行时多态示例
    std::vector<std::unique_ptr<Shape>> shapes;
    
    shapes.push_back(std::make_unique<Circle>(5.0));
    shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
    shapes.push_back(std::make_unique<Circle>(3.5));
    
    for (const auto& shape : shapes) {
        shape->draw(); // 调用适当的draw()方法
        std::cout << "Area: " << shape->area() << std::endl;
        std::cout << "---" << std::endl;
    }
    
    // 编译时多态示例
    Print::display(10);
    Print::display(3.14);
    Print::display("Hello Polymorphism");
    
    return 0;
}

4.三者之间的关系

4.1封装是基础:

隐藏实现细节,定义清晰的接口

使继承和多态成为可能

4.2继承拓展功能

建立类之间的层次关系

为多态提供结构基础

4.3多态增强灵活性

利用继承关系实现统一接口

需要封装保护内部状态