十、虚函数与多态
10.1 虚函数基础
#include <iostream>
using namespace std;
class Animal {
public:
// 虚函数:支持动态绑定
virtual void speak() {
cout << "动物发出声音" << endl;
}
// 纯虚函数:抽象类
virtual void move() = 0;
// 虚析构函数
virtual ~Animal() {
cout << "Animal析构" << endl;
}
};
class Dog : public Animal {
public:
void speak() override { // override显式标记重写
cout << "汪汪汪" << endl;
}
void move() override {
cout << "狗在跑" << endl;
}
~Dog() override {
cout << "Dog析构" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "喵喵喵" << endl;
}
void move() override {
cout << "猫在跳" << endl;
}
};
int main() {
// 多态使用
Animal* ptr1 = new Dog();
Animal* ptr2 = new Cat();
ptr1->speak(); // 调用Dog的speak
ptr1->move(); // 调用Dog的move
ptr2->speak(); // 调用Cat的speak
ptr2->move(); // 调用Cat的move
delete ptr1;
delete ptr2;
return 0;
}
10.2 虚函数表
#include <iostream>
using namespace std;
class Base {
public:
virtual void func1() { cout << "Base::func1" << endl; }
virtual void func2() { cout << "Base::func2" << endl; }
void func3() { cout << "Base::func3" << endl; }
};
class Derived : public Base {
public:
void func1() override { cout << "Derived::func1" << endl; }
virtual void func4() { cout << "Derived::func4" << endl; }
};
int main() {
// 查看对象大小(虚函数表指针)
cout << "sizeof(Base) = " << sizeof(Base) << endl; // 8字节(64位系统)
cout << "sizeof(Derived) = " << sizeof(Derived) << endl; // 8字节
// 动态类型识别
Base* ptr = new Derived();
// typeid获取类型信息
cout << "typeid(*ptr).name() = " << typeid(*ptr).name() << endl;
// dynamic_cast向下转型
Derived* dptr = dynamic_cast<Derived*>(ptr);
if (dptr) {
dptr->func4();
}
delete ptr;
return 0;
}
十一、异常处理中的函数
#include <iostream>
#include <stdexcept>
using namespace std;
// 可能抛出异常的函数
double divide(double a, double b) {
if (b == 0) {
throw invalid_argument("除数不能为零");
}
return a / b;
}
// 异常规范(C++11后已弃用)
// void func() throw(int, char); // 可能抛出int或char
// void func() throw(); // 不抛出任何异常
// noexcept函数(C++11)
void safeFunc() noexcept {
// 保证不抛出异常
cout << "安全函数" << endl;
}
// 可能抛出异常的noexcept函数
void maybeThrow() noexcept(false) {
throw runtime_error("可能抛出");
}
// 异常安全的函数设计
class SafeCalculator {
public:
double divide(double a, double b) {
if (b == 0) {
throw invalid_argument("除数不能为零");
}
return a / b;
}
// 强异常安全保证
void transfer(int from, int to, double amount) {
double temp = getBalance(from);
if (temp < amount) {
throw runtime_error("余额不足");
}
// 先更新from
setBalance(from, temp - amount);
try {
setBalance(to, getBalance(to) + amount);
} catch (...) {
// 发生异常时恢复from
setBalance(from, temp);
throw;
}
}
private:
double getBalance(int account) { return 0; }
void setBalance(int account, double amount) {}
};
int main() {
try {
double result = divide(10, 0);
cout << "结果: " << result << endl;
} catch (const invalid_argument& e) {
cerr << "参数错误: " << e.what() << endl;
} catch (const exception& e) {
cerr << "异常: " << e.what() << endl;
}
safeFunc();
try {
maybeThrow();
} catch (...) {
cout << "捕获异常" << endl;
}
return 0;
}
十二、函数最佳实践
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
// 1. 使用const引用传递大对象
void processData(const vector<int>& data) {
// 避免拷贝,使用const确保不修改
}
// 2. 返回局部对象时依赖RVO/NRVO
vector<int> createData() {
vector<int> result;
result.reserve(100);
// 填充数据
return result; // 编译器会优化,不会拷贝
}
// 3. 使用移动语义
class Buffer {
private:
unique_ptr<char[]> data;
size_t size;
public:
// 移动构造函数
Buffer(Buffer&& other) noexcept
: data(move(other.data)), size(other.size) {
other.size = 0;
}
// 移动赋值
Buffer& operator=(Buffer&& other) noexcept {
if (this != &other) {
data = move(other.data);
size = other.size;
other.size = 0;
}
return *this;
}
// 禁止拷贝
Buffer(const Buffer&) = delete;
Buffer& operator=(const Buffer&) = delete;
};
// 4. 使用默认参数简化接口
void log(const string& message, int level = 0, bool timestamp = true) {
if (timestamp) {
cout << "[TIME] ";
}
cout << string(level, ' ') << message << endl;
}
// 5. 使用noexcept提升性能
void swapNoexcept(int& a, int& b) noexcept {
int temp = a;
a = b;
b = temp;
}
// 6. 使用inline建议编译器内联
inline int square(int x) noexcept {
return x * x;
}
// 7. 函数设计原则:单一职责
// 不好
void processUser(string name, int age, string email) {
// 验证、保存、发送邮件混在一起
}
// 好
bool validateUser(const string& name, int age, const string& email);
void saveUser(const string& name, int age, const string& email);
void sendWelcomeEmail(const string& email);
int main() {
log("系统启动");
log("用户登录", 1);
log("错误", 2, true);
int a = 10, b = 20;
swapNoexcept(a, b);
cout << "a=" << a << ", b=" << b << endl;
cout << "square(5) = " << square(5) << endl;
return 0;
}
C++函数体系在继承C语言函数特性的基础上,引入了众多强大的新特性:函数重载、默认参数、内联函数、Lambda表达式、函数对象、模板函数、虚函数等。这些特性使得C++函数设计更加灵活、高效和现代化。本文系统性地梳理了C++函数的核心知识点,从基础到高级,从面向对象到泛型编程,帮助开发者建立完整的知识体系。
来源:
https://xcfsr.cn/category/ai.html