C++ 重载函数、运算符重载、抽象类(接口)

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 两种实现方式

  1. 成员函数重载 :左操作数是 this,参数较少
  2. 全局函数重载:通常需要声明为类的友元

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;
}
相关推荐
倒头就睡的小比特20 小时前
算法竞赛C++常用的STL
c++·算法
weilx123421 小时前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!21 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
Smileyqp沛沛1 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·1 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven1 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法