12 多态
虚函数
- 当派生类的对象使用它基类的指针(或引用)调用虚函数时,将调用该对象的成员函数。如果没有使用virtual,将调用基类的成员函数。
- 在公有继承层次中,某个类的成员函数申明为 virtual。则其直接或间接派生类中的相同签名的函数,都是虚函数。不论是否用关键字 virtual 再次申明。
- 任何虚函数,都有可能被其派生类再次重新定义,重新定义后依然是虚函数。因此,虚函数既可以被继承,也可以被重新定义。
override和overwrite的区别
override(覆盖) 必须满足 3 个条件:
- 基类函数必须有
virtual - 子类函数 和父类完全一样(名字、参数、返回值、const)
- 发生在 继承 + 虚函数 中
作用:实现多态
overwrite(隐藏) 只要满足 1 个条件:
- 子类和父类函数同名 (不管参数是否相同,只要没有 virtual)
作用:子类把父类函数藏起来,不让你调用
右值引用
右值引用(Rvalue Reference)是 C++11 引入的核心特性,语法是 T&&。它本质上是一种绑定到临时对象(右值)的引用,目的是"偷走"临时对象的资源而不是拷贝它们。
右值引用 vs const& 的区别
| 特性 | const 左值引用 const T& | 右值引用 T&& |
|---|---|---|
| 绑定左值 | ✅ 可以 | ❌ 不可以 |
| 绑定右值 | ✅ 可以 | ✅ 可以 |
| 能否修改值 | ❌ 不能 | ✅ 能 |
| 用途 | 函数传参、只读、延长临时生命 | 移动构造、移动赋值、修改临时对象 |
析构时机
std::string make() { return std::string("hello"); }
void foo() {
std::string&& r = make(); // make() 返回纯右值(临时对象)
// ...
} // 临时对象在这里析构,寿命被延长到 foo 结束
| 绑定来源 | 是否延长寿命 | 析构时机 |
|---|---|---|
纯右值(如 foo() 返回值、T() 临时构造) |
✅ 延长 | 右值引用变量作用域结束 |
将亡值 xvalue(std::move(obj)) |
❌ 不延长 | obj 原本的生命周期结束时 |
| 左值(通过万能引用或非法绑定) | ❌ 不延长 | 原左值正常析构 |
动态类型和静态类型
- 静态类型:编译时看变量本身声明的类型
- 动态类型:运行时指针/引用实际指向的对象真实类型
class Fruit{
public:
void say() {
printf("I'm a fruit!\n");
}
};
class Apple : public Fruit {
public:
void say() {
printf("I'm an apple!\n");
}
};
int main(){
Apple a;
Fruit *fPtr = &a;
fPtr->say();
}
(*fPtr) 的动态类型为 Apple