C++ overload、override、overwrite

本文详细探讨了C++中的函数重载(overload)、覆盖(override)和重写(overwrite)的概念。重载不考虑返回类型,仅通过参数列表区分;覆盖要求函数名、参数列表和返回值类型一致,且基类函数需为虚函数。重写则可能导致基类函数被隐藏。在子类中,未被覆盖的重载函数会被隐藏,只能通过基类调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于函数的重载(overload)、覆盖(override)、重写(overwrite)三者的理解,通过代码来分析。

重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载解析中不考虑返回类型,而且在不同的作用域里声明的函数也不算是重载。

class A{
public:
  void func(int i);
  void func(double i);//overload
  void func(int i, double j);//overload
  void func(double i, int j);//overload
  int func(int i);         //非重载。注意重载考虑函数返回类型。
};

覆盖:是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

#include<iostream>
using namespace std;

class Base
{
public:
    virtual void fun(int i){ cout << "Base::fun(int) : " << i << endl;}
};

class Derived : public Base
{
public:
    virtual void fun(int i){ cout << "Derived::fun(int) : " << i << endl;}
};
int main()
{
    Base b;
    Base * pb = new Derived();   //向上造型
    pb->fun(3);                  //Derived::fun(int)

    delete pb;
    system("pause");
    return 0;
}

重写
是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

class Base{
public:
    virtual int fcn();
};
class D1:public Base{
public:
    //隐藏基类的fcn,这个fcn不是虚函数
    //D1继承了Base::fcn()的定义
    int fcn(int);         //形参类别与Base中的fcn不一样
    virtual void f2();    //是一个新的虚函数,在Base中不存在
};
class D2:public D1{
publicint fcn(int);        //是一个非虚函数,隐藏了D1::fcn(int)
    int fcn();           //覆盖了Base的虚函数fcn
    void f2();           //覆盖了D1的虚函数f2

D1的fcn函数并没有覆盖Base的虚函数fcn,原因是他们的形参列表不同。实际上,D1的fcn将隐藏Base的fcn。此时拥有了两个名为fcn的函数,一个D1从Base继承而来的虚函数fcn,另一个是D1自己定义的接收一个int参数的非虚函数fcn。

下面写一个例子,可以通过定义基类是否有virtual关键字来帮助判断。

// test.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <iostream>
using namespace std;

class A {
public:
    A() {}
    void print(int x);    //定义函数
    void print(int x, int y);
    void print();
    ~A() {}
};
void A::print(int x)
{
    cout << "A::print(int x)" << endl;
}
void A::print(int x, int y)
{
    cout << "A::print(int x,int y)" << endl;
}
void A::print()
{
    cout << "A::print()" << endl;
}
class B :public A {
public:
    B() {}
    void print(int x);
    ~B() {}
};

int main()
{
    A a;
    B b;
    a.print(1);
    a.print(1,2);
    b.print(1);
    b.print(1,2);     //错误,函数不接受2个参数
    return 0;
}

在上面的b.print(1,2) 中提示错误,其实是如果基类定义了overloaded(重载)函数,那么在子类必须override(覆盖)所有你所定义的overloaded(重载)函数,不能只override一个,如果没有override所有重载函数,那么没有被override的将会被隐藏,只能父类调用,不能子类调用。

### Java中的OverrideOverwriteOverload #### Override方法 在面向对象编程中,`override`是指子类重新定义父类的方法。这允许子类提供特定实现来替代继承自父类的行为。为了成功覆盖一个方法,在子类中声明的方法签名(包括名称、参数列表以及返回类型)应当与父类中的被重写方法相匹配。 ```java class Animal { public void makeSound() { System.out.println("Some sound"); } } class Dog extends Animal { @Override public void makeSound() { System.out.println("Bark bark!"); } } ``` 上述例子展示了如何通过使用`@Override`注解来指示编译器该方法意在覆盖超类中的同名方法[^1]。 #### Overload方法 不同于`override`,`overload`发生在同一个类内部,当多个具有相同名字但是不同参数列表的方法存在时即发生过载。这意味着这些方法可以有不同的数量或类型的输入参数,甚至它们的顺序也可以不一样;然而,返回值类型并不影响是否构成重载的一部分条件之一。 ```java public class Calculator { int add(int a, int b){ return a+b; } double add(double a,double b){ return a+b; } float add(float a,float b,int c){ return a+b+c; } } ``` 此代码片段说明了一个名为`add()`函数的不同版本是如何在同一类内共存并根据调用时传递给它的实参自动选择最合适的那个版本执行[^2]。 #### 关于Overwrite概念 值得注意的是,“overwrite”并不是Java官方术语,通常指的是文件操作里的一种行为——新数据会替换旧有位置上的内容而不增加额外存储空间。但在讨论OOP特性时不常用到这个词。如果提到它,则可能指代错误地隐藏了基类成员变量或方法而不是正式意义上的多态机制下的合法覆写过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值