一、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多态增强灵活性
利用继承关系实现统一接口
需要封装保护内部状态