C++基础篇--overload重载&override覆盖&overwrite隐藏

    Overload、Override和Overwrite英文接近,比较容易混淆,再加上翻译五花八门,使用时张冠李戴,往往是今天清楚明天糊涂。这三个概念在前面章节已分别讨论,这里再集中比较,以作备忘:

Overload
(重载)

前面分析过C++函数重载是借助C++的name mangling机制,允许在同一作用域中出现多个同名不同参的函数,如:

class Base{

int output(int a) {……};

int output(float b, float c){……};

}

这是重载,特点:

1)同名不同参:两个同名同参的函数绝不是重载,注意参数有无const也视为不同;

2)仅仅返回值不同,不构成重载;

3)相同作用域:同一文件域/全局域/namespace域内的同名不同参函数可以构成重载;而对于类成员函数,重载必须发生在同一类域中,分属于基类与派生类的函数不能直接构成重载(派生类函数重载基类函数的说法错误)。

Override
(覆盖)

在派生类中重新定义实现基类中的虚函数,这个过程就是override(译为覆盖),如:

class Base{

virtual void output() { cout << "Base::output()"<< endl;}

};

class Drv0 : public Base{

void output () { cout << "Drv0:: output()" << endl; }

};

这里Drv0::output就是覆盖(override)了Base::output(有人会错用重载overload),覆盖的特征:

1)不同作用域(分别位于派生类与基类);

2)基类函数须为virtual函数,而派生类重新实现的函数需与基类虚函数同名同参。

Overwrite:隐藏(翻译最乱,也有称重定义、重写或屏蔽)

指派生类的函数屏蔽与其同名的基类函数,发生在不同类域(派生类与基类之间),具体情形包括:

1)派生类与基类函数同名但不同参,此时不论基类函数是否virtual,其都将被派生类函数隐藏。(不要与重载混淆,重载发生在同一类域)

2)派生类函数与基类非virtual函数同名同参,此时基类函数被隐藏(不要与覆盖混淆,覆盖特指基类函数为virtual的情况)

梳理后的逻辑:类public派生时,基类成员全部继承到派生类,除非派生类有同名;当派生类与基类成员有同名,除了基类成员为virtual函数时属于覆盖(override),其他情况都是隐藏。

区分

1) overload原理上与override/overwrite没有实质的关联和相似,overload是同一个类中的成员函数间的水平关系;而override/overwrite都是派生类和基类间的垂直关系,只要涉及派生类/基类函数间的关系就不可能是overload。只是overload译成重载,其字面含义与实际功能并不能形象匹配,反而暗示一种上下层间的垂直关系,导致派生类覆盖override或隐藏overwrite基类函数时常被误称为重载,因此只要留心,很容易把overload(重载)区别出来。

2) override覆盖的前提或特点是基类函数必须为virtual,派生类中同名同参重新实现基类的virtual函数就是override,覆盖后可通过基类指针指向的具体对象类型确定调用哪个方法,从而实现函数多态;而overwrite(隐藏)是指派生类的函数屏蔽与其同名的基类非virtual函数,使其不能被派生类对象直接引用。

下例说明覆盖与隐藏的区别:

class Base

{

virtual void a(int x){  cout << "Base::a(int) "<< x << endl;  }

void b(int x){  cout << "Base::b(int) "<< x << endl;  }

};

class Drv0 : public Base

{

virtual void a(int x){  cout << "Drv0::a(int) "<< x << endl;  }

void b(int x){  cout << "Drv0::b(int) "<< x << endl;  }

};

void main()

{

Drv0 d;

Base *pbase = &d;

Drv0 *pdrv = &d;

pbase->a(3);  //输出Drv0::a(int) 3

pdrv->a(3);  //
输出Drv0::a(int) 3

pdrv->b(3); //  输出Drv0::b(int) 3

pbase->b(3); //
输出Base::b(int) 3

}

例中Drv0::a(int)覆盖override了Base::a(int),因此不管是通过基类指针调用pbase->a(3),还是通过派生类指针调用pdrv->a(3),最终都是根据对象类型(Drv0
d;)选择调用函数
,结果都为Drv0::a(int) 3

而Drv0::b(int)则隐藏overwrite了Base::b(int),外在表现就是根据指针类型(Base*
pbase和Drv0* pdrv)决定调用函数
,即pdrv->b(3)输出Drv0::b(int) 3,而pbase->b(3)输出Base::b(int)
3。因此隐藏相当于对于某一功能派生类另起炉灶,基类和派生类各干各的。

    所以覆盖的结果是根据对象类型决定调用哪个函数(多态);而隐藏则表现为根据指针类型决定调用哪个函数,这是覆盖和隐藏最直观的区别

隐藏overwrite是对函数继承的破坏,多数情况没有必要,因为基类中非virtual型成员函数本就代表类的功能中不变的部分,派生类 应该直接继承使用而不需修改,发生overwrite多数说明设计不完善。

实际上很多时候是不小心把override实现成了overwrite,即本该把基类函数设计为virtual以实现可变功能,却忘了写virtual,结果当在派生类中重写同名函数时就成了overwrite隐藏。

时间: 2024-11-02 14:16:33

C++基础篇--overload重载&override覆盖&overwrite隐藏的相关文章

C++中的Overload、Override和Overwrite

在C++语言中有一组基础的概念一直都容易混淆:Overload.Override和Overwrite分别表示什么意思?下面把这三个概念整理一下: 1. Overload(重载) 重载的概念最好理解,在同一个类声明范围中,定义了多个名称完全相同.参数(类型或者个数)不相同的函数,就称之为Overload(重载).重载的特征如下: (1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无. 2. Override(覆盖) 覆盖的概念其实是用来实现C+

C++中成员函数的重载、覆盖和隐藏的区别

转载请注明,原创地址:点击打开链接   http://blog.csdn.net/u010587274/article/details/38928561 个人微信公众号:tanzi_888 (潭子技术圈) C++中成员函数的重载.覆盖和隐藏的区别: 1 重载(overload): 是函数名相同,参数列表不同 重载只是在类的内部存在.但是不能靠返回值类型来判断.1.1)相同的范围(在同一个类中)1.2)函数名字相同1.3)参数不同 1.4)Virtual关键字可有可无 2  覆盖 (overrid

重载、覆盖和隐藏

部分文字内容摘自<高质量C++/C编程> 链接:http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 1 重载 Overload 1) 相同的范围,在同一个类中. 2) 函数名相同,参数不同. 3) virtual可有可无. 这在平时设计中用的比较多,比如游戏中角色说话,可以设计成: void SendDialog(const char* content); // 默认 void SendDialog(const ch

c++重载、覆盖和隐藏

c++成员函数的重载.覆盖和隐藏很容易混淆,因此我们必须搞清楚这一点. 1.重载 重载特点:同一访问区域(同类).函数名称相同.函数参数不同(不关心返回类型).virtual关键字可有可无. 代码示例: class OverLoad { public: void test() {} void test(int i) {} void test(float i) {} void test(int i, float j) {} }; 2.覆盖 覆盖是指派生类函数覆盖基类函数,特点是:不同访问区域(不同

C++中的重载、覆盖和隐藏的区分

C++中经常用到重载.覆盖和隐藏这三个概念,也经常容易搞混.所以,这篇博文来整理一下它们之间的异同. 1. 重载--实现多态性 A.相同的范围(同一个类中) B.函数的名字相同 C.参数类型不同(不能进行隐式类型转换) D.Virtual关键字可有可无 2. 覆盖(重写)--派生类函数覆盖基类函数 A.不同的范围(分别位于基类与派生类中) B.函数名字相同 C.参数相同 D.基类函数必须有virtual关键字 3. 隐藏(重定义)--派生类的函数屏蔽了与其同名的基类函数 A.如果派生类的函数与基

C++中类成员函数的重载、覆盖和隐藏(转自牛客网)

问题 (多选)类成员函数的重载.覆盖和隐藏区别描述正确的有? [ ] A. 覆盖是指在同一个类中名字相同,参数不同 [ ] B. 重载是指派生类函数覆盖基类函数,函数相同,参数相同,基类函数必须有virtual关键字 [ ] C. 派生类函数与基类函数相同,但是参数不同,会"隐藏"父类函数 [ ] D. 函数名字相同,参数相同,基类无virtual关键字的派生类的函数会"隐藏"父类函数 答案 C.D 解析 A选项:同一个类中,名字相同,参数不同,是重载不是覆盖. B

C++ 成员函数的重载与覆盖与隐藏

重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual 关键字可有可无. 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类): (2)函数名字相同: (3)参数相同: (4)基类函数必须有 virtual 关键字. 函数 Base::f(int)与 Base::f(float)相互重载,而 Base::g(void) 被 Derived::g(void)覆盖. #include <ios

C++函数的重载,覆盖和隐藏(——高质量编程)

函数重载概念 只有C++才有重载的概念,C语言没有. 靠行参列表的不同来区别不同的重载函数, 若是全局函数和成员函数同名时,不算重载,因为它们的作用域不同,所以成员函数会将全局函数给隐藏(遮蔽)了. 成员函数的重载,覆盖和隐藏 重载发生在相同的作用域中,而覆盖则发生在不同的作用域中 重载: 相同的作用域 函数的名字相同 函数的形参列表,顺序,类型,个数不同 virtual可有可无 覆盖: 作用域不同,属于不同的类中 函数的名字相同 形参列表相同 基类必须是虚函数

C++:类成员函数的重载、覆盖和隐藏区别?

#include <iostream> class A { public: void func() { std::cout << "Hello" << std::endl; } void func(int k) { } }; class B : public A { public: using A::func; // 把这句注释掉试试,嘿嘿 void func(int i) { } }; int main() { B b; b.func();//编译