C中类成员函数的重写、重载和隐藏的区别是什么?

### C++中类成员函数的重写、重载和隐藏的区别

在C++中,类成员函数的重载、重写和隐藏是三个重要的概念,它们在不同的场景下有着不同的行为和用途。下面将详细解释这三个概念的区别,并给出具体的示例。

#### 1. 重载(Overload)

**定义**:在同一作用域内,当存在同名成员函数时,如果这些函数的参数列表不同(包括类型、数目或顺序),则可以被视为重载。返回值类型的不同不会影响重载的判断。

**特征**:
- **相同的范围**:在同一个类中。
- **函数名字相同**。
- **参数不同**:包括参数类型、参数个数或参数顺序的不同。
- **virtual关键字可有可无**:重载靠的是函数标识符,与`virtual`关键字无关。

**示例**:
```cpp
class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }
};
```
在这个例子中,`Calculator`类中有三个名为`add`的函数,它们的参数列表不同,因此它们是重载的。

#### 2. 重写(Override)

**定义**:重写是指在派生类中覆盖基类中的同名虚函数。重写要求派生类中的函数体与基类中的虚函数体相同,且参数列表和返回值与基类虚函数相同。通过使用`override`关键字确保这是对基类虚函数的重写。

**特征**:
- **不同的范围**:分别位于派生类与基类。
- **函数名字相同**。
- **参数相同**。
- **基类函数必须有virtual关键字**:子类可有可不有,没有的话编译器会自动加上`virtual`。

**示例**:
```cpp
class Base {
public:
    virtual void display() {
        cout << "Display from Base" << endl;
    }
};

class Derived : public Base {
public:
    void display() override {
        cout << "Display from Derived" << endl;
    }
};
```
在这个例子中,`Derived`类重写了`Base`类中的`display`虚函数。

#### 3. 隐藏(Hide)

**定义**:隐藏是指派生类中的函数在某些情况下会屏蔽基类中的同名函数。隐藏是通过将基类函数的作用域进行隐藏实现的,因此可以通过作用域解析符`::`来访问基类函数。隐藏与重载的区别在于,隐藏是基于函数参数的匹配,而重载是基于函数名和参数列表的匹配。

**特征**:
- **子类函数与基类函数同名不同参**:不论有无`virtual`,基类的所有同名函数被隐藏。
- **调用基类函数时必须显式加上“基类名::”**  :如果不加的话会在编译截断报错,因为编译器会做尝试:
  - 在参数数量相同时进行隐式类型转换,转换不了就会报错,而不是往基类中寻找;
  - 在参数数量不同时直接报错。

**示例**:
```cpp
class Base {
public:
    void show() {
        cout << "Show from Base" << endl;
    }

    void show(int x) {
        cout << "Show from Base with int" << endl;
    }
};

class Derived : public Base {
public:
    void show(double x) {
        cout << "Show from Derived with double" << endl;
    }
};
```
在这个例子中,`Derived`类中的`show(double x)`函数隐藏了`Base`类中的`show()`和`show(int x)`函数。如果通过`Derived`对象调用`show()`或`show(int x)`,编译器会报错,因为这些函数被隐藏了。可以通过`Base::show()`或`Base::show(int x)`来显式调用基类的函数。

### 总结

- **重载**:在同一作用域内,函数名相同但参数列表不同。
- **重写**:在派生类中覆盖基类的虚函数,要求函数名、参数列表相同,基类函数必须有`virtual`关键字。
- **隐藏**:派生类中的函数屏蔽了与其同名的基类函数,不论参数是否相同。

### 表格总结

| 特征       | 重载 (Overload)                                                                 | 重写 (Override)                                                                 | 隐藏 (Hide)                                                                 |
|------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
| 作用域     | 同一个类中                                                                      | 派生类与基类                                                                    | 派生类与基类                                                                    |
| 函数名     | 相同                                                                            | 相同                                                                            | 相同                                                                            |
| 参数       | 不同(类型、数目或顺序)                                                        | 相同                                                                            | 不同或相同                                                                      |
| virtual    | 可有可无                                                                        | 必须有                                                                          | 无关                                                                            |
| 调用方式   | 根据参数列表确定                                                                | 动态绑定,通过虚函数表                                                          | 静态绑定,通过作用域解析符`::`                                                  |
| 应用场景   | 提供函数的多种使用方式                                                          | 实现多态性                                                                      | 可能导致不易察觉的错误,需要特别注意                                              |

通过以上详细解释和示例,可以清晰地理解C++中类成员函数的重载、重写和隐藏的区别及其应用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值