C++ 重载函数、运算符重载、抽象类(接口)
一、函数重载(Function Overloading)
1.1 概念
在同一作用域 下,允许定义同名函数 ,只要参数列表不同 (参数个数、类型、顺序不同),与返回值无关。
编译器会根据实参自动匹配最优函数,实现"同一接口,多种实现"。
1.2 重载规则
- 函数名必须相同
- 参数列表必须不同(个数/类型/顺序)
- 返回值不同不能构成重载
- 成员函数、全局函数均可重载
- 构造函数天然支持重载
1.3 完整代码示例
cpp
#include <iostream>
#include <string>
using namespace std;
// 全局函数重载
void show(int a) {
cout << "int: " << a << endl;
}
void show(double a) {
cout << "double: " << a << endl;
}
void show(string a) {
cout << "string: " << a << endl;
}
void show(int a, double b) {
cout << "int+double: " << a << ", " << b << endl;
}
// 类成员函数重载
class Test {
public:
void print(int x) {
cout << "成员 int: " << x << endl;
}
void print(string s) {
cout << "成员 string: " << s << endl;
}
};
int main() {
show(10);
show(3.14);
show("hello");
show(10, 20.5);
Test t;
t.print(666);
t.print("test");
return 0;
}
二、运算符重载(Operator Overloading)
2.1 本质
本质是函数重载 ,关键字 operator,让自定义对象支持 + - * / == << ++ 等运算。
2.2 两种实现方式
- 成员函数重载 :左操作数是
this,参数较少 - 全局函数重载:通常需要声明为类的友元
2.3 不可重载运算符
:: 、.* 、. 、sizeof 、?:
2.4 常用运算符重载 + 完整代码
以 Point 类为例,实现加减、输出、自增、相等判断、赋值等重载。
cpp
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// 1. 加号 + 重载(成员函数)
Point operator+(const Point& p) const {
return Point(x + p.x, y + p.y);
}
// 2. 减号 - 重载
Point operator-(const Point& p) const {
return Point(x - p.x, y - p.y);
}
// 3. 前置 ++
Point& operator++() {
x++;
y++;
return *this;
}
// 4. 后置 ++(int 是占位符)
Point operator++(int) {
Point temp = *this;
x++;
y++;
return temp;
}
// 5. 相等 ==
bool operator==(const Point& p) const {
return x == p.x && y == p.y;
}
// 6. 赋值 =(深拷贝,有堆内存时必须写)
Point& operator=(const Point& p) {
if (this == &p) return *this;
x = p.x;
y = p.y;
return *this;
}
// 7. 输出 << 必须全局重载
friend ostream& operator<<(ostream& os, const Point& p);
};
// 实现 << 重载
ostream& operator<<(ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
int main() {
Point p1(1, 2);
Point p2(3, 4);
Point p3 = p1 + p2;
cout << "p1+p2 = " << p3 << endl;
Point p4 = p2 - p1;
cout << "p2-p1 = " << p4 << endl;
++p1;
cout << "++p1 = " << p1 << endl;
p1++;
cout << "p1++ = " << p1 << endl;
if (p1 == p2)
cout << "p1 == p2" << endl;
else
cout << "p1 != p2" << endl;
Point p5;
p5 = p3;
cout << "p5 = " << p5 << endl;
return 0;
}
2.5 重点规则
<</>>必须全局重载=/[]/()/->必须成员重载- 前置
++返回引用 ,后置返回临时对象 - 赋值运算符要处理自赋值,有堆内存必须深拷贝
三、抽象类与接口(Abstract Class & Interface)
3.1 纯虚函数
cpp
virtual void func() = 0;
没有函数体,只有声明,用于强制子类实现。
3.2 抽象类
包含至少一个纯虚函数的类。
- 不能实例化对象
- 用于统一接口规范
- 子类必须重写所有纯虚函数,否则仍是抽象类
3.3 接口(C++ 模拟接口)
C++ 无 interface 关键字,用全部是纯虚函数的类表示接口。
3.4 完整代码示例
cpp
#include <iostream>
using namespace std;
// 接口 1:可飞行
class Flyable {
public:
virtual void fly() = 0; // 纯虚函数
virtual ~Flyable() {} // 虚析构,防止内存泄漏
};
// 接口 2:可鸣叫
class Speakable {
public:
virtual void speak() = 0;
virtual ~Speakable() {}
};
// 鸟类实现两个接口
class Bird : public Flyable, public Speakable {
public:
void fly() override {
cout << "鸟用翅膀飞" << endl;
}
void speak() override {
cout << "鸟叽叽喳喳叫" << endl;
}
};
// 飞机实现飞行接口
class Plane : public Flyable {
public:
void fly() override {
cout << "飞机用引擎飞" << endl;
}
};
// 统一接口调用(多态)
void doFly(Flyable* f) {
f->fly();
}
int main() {
Flyable* f1 = new Bird();
Flyable* f2 = new Plane();
doFly(f1);
doFly(f2);
Speakable* s = new Bird();
s->speak();
delete f1;
delete f2;
delete s;
return 0;
}
3.5 核心要点
- 抽象类不能创建对象
- 接口 = 全纯虚函数的抽象类
- 析构函数必须是
virtual - 子类必须实现所有纯虚函数
- 支持多接口继承(多继承)
四、三合一综合示例
cpp
#include <iostream>
#include <string>
using namespace std;
// 抽象类(接口)
class Animal {
public:
virtual void sound() = 0;
virtual ~Animal() {}
};
// 重载函数
void show(Animal* a) {
a->sound();
}
void show(string s) {
cout << s << endl;
}
// 狗类
class Dog : public Animal {
private:
int age;
public:
Dog(int a) : age(a) {}
void sound() override {
cout << "汪汪汪" << endl;
}
// 运算符 == 重载
bool operator==(const Dog& d) const {
return age == d.age;
}
};
int main() {
Animal* a = new Dog(3);
show(a);
show("测试重载函数");
Dog d1(2), d2(2);
if (d1 == d2)
cout << "年龄相同" << endl;
delete a;
return 0;
}