1.final 与 override 关键字
这两个关键字专门用于类继承 + 虚函数重写,作用是:编译期强制校验语法,杜绝隐藏 bug,是 C++ 多态的安全规范。
1. override:强制检查「虚函数重写」
核心作用
1.只能修饰子类的虚函数;
2.告诉编译器:这个函数必须是重写基类的虚函数;
3.如果函数名 / 参数 / 返回值写错,直接编译报错(传统写法不会报错,会变成新函数,导致多态失效)。
语法:
cpp
// 子类虚函数末尾加 override
void 函数名(参数) override;
代码示例:
cpp
#include <iostream>
using namespace std;
// 基类
class Base {
public:
virtual void show() { cout << "Base\n"; }
};
// 子类
class Derive : public Base {
public:
// ✅ 正确:重写基类虚函数,override 校验通过
void show() override { cout << "Derive\n"; }
// ❌ 错误:函数名写错(shou),编译器直接报错!
// void shou() override { cout << "Derive\n"; }
};
必须用 override:它是虚函数重写的「保险栓」,彻底避免因手误导致的多态失效。
2. final:禁止重写 / 禁止继承
有两种用法,语义完全不同:
用法 1:修饰虚函数 → 禁止子类重写:
cpp
class Base {
public:
// 该虚函数无法被任何子类重写
virtual void func() final { cout << "final func\n"; }
};
class Derive : public Base {
public:
// ❌ 报错:无法重写 final 函数
// void func() override {}
};
用法 2:修饰类 → 禁止该类被继承:
cpp
// 最终类,不能有子类
class FinalClass final { };
// ❌ 报错:无法继承 final 类
// class Son : public FinalClass { };
2.智能指针 (Smart Pointers)
C++ 用 new 动态分配的内存,必须手动 delete,否则会内存泄漏。
智能指针:封装裸指针的类,离开作用域时自动调用 delete 释放内存,无需手动管理,从根源避免泄漏。
1. std::unique_ptr:独占式智能指针(最常用)
特性:
- 同一时间只有一个指针拥有对象所有权;
- 禁止拷贝,只能移动(转移所有权);
- 性能和裸指针完全一致,无额外开销;
- 默认优先使用它!
用法示例:
cpp
#include <iostream>
#include <memory>
using namespace std;
int main() {
// 1. 创建 unique_ptr,管理 int 对象
unique_ptr<int> p1(new int(10));
cout << *p1 << endl; // 10
// 2. 移动语义:转移所有权(p1 变为空)
unique_ptr<int> p2 = move(p1);
cout << *p2 << endl; // 10
// 3. 离开作用域,自动释放内存,无需 delete
return 0;
}
2. std::shared_ptr:共享式智能指针
特性:
多个指针共享同一个对象;
内部维护引用计数:
拷贝 → 计数 + 1
析构 → 计数 - 1
计数 = 0 → 自动释放内存
有轻微性能开销(维护计数)
用法示例:
cpp
int main() {
// 创建 shared_ptr
shared_ptr<int> p1(new int(20));
cout << "计数:" << p1.use_count() << endl; // 1
// 拷贝,共享所有权
shared_ptr<int> p2 = p1;
cout << "计数:" << p1.use_count() << endl; // 2
// 所有指针失效后,内存自动释放
return 0;
}
3. std::weak_ptr:弱引用指针(解决循环引用)
核心问题:
shared_ptr 会出现循环引用:两个对象互相持有对方的 shared_ptr,计数永远不为 0,内存泄漏。
特性:
不拥有对象所有权,不增加引用计数;
仅作为「观察者」,监测对象是否存活;
必须配合 shared_ptr 使用。
核心方法:
expired():判断对象是否已释放
lock():转为 shared_ptr 访问对象
总结:
1.优先用 std::make_unique/std::make_shared 创建智能指针(更安全、高效)
cpp
auto p = make_unique<int>(10);
auto sp = make_shared<double>(3.14);
2.不要混用裸指针和智能指针;
3.不要手动 delete 智能指针管理的内存;
4.能用 unique_ptr 绝不用 shared_ptr(性能最优)。
谢谢