重温《C++ Primer》笔记五 类定义中成员函数的名字隐藏(虚函数与非虚函数)
来源:互联网 发布:vb用的是什么语言 编辑:程序博客网 时间:2024/06/15 08:38
类定义中大致有两种函数——普通函数和虚函数。如果对一个类继承并且对其中的成员函数重新进行定义,也可以分为两种情况:
1、在派生类的定义中明确地定义操作和返回类型,称之为普通成员函数的重定义(redefining);
2、对虚函数的重定义成为重写(overriding);
下面的程序是摘自《Thinking in C++》上的一段,可以用来解释发生在函数重定义过程中的名字隐藏(这里的名字指的是函数的名字):
#include <iostream>#include <string>using namespace std;class Base{public:int f() const{cout<<"Base::f()\n";return 1;}int f(string) const {return 1;}void g() {}};class Derived1 : public Base{public:void g() const {}};class Derived2 : public Base{public:int f() const{cout<<"Derived2::f()\n";return 2;}};class Derived3 : public Base{public:void f() const{cout<<"Derived3::f()\n";}};class Derived4 : public Base{public:int f(int) const{cout<<"Derived4::f()\n";return 4;}};int main(){string s("hello");Derived1 d1;int x = d1.f();d1.f(s);Derived2 d2;x = d2.f();d2.f(s);return 0;}首先,Derived1只重定义了父类的g()函数,没有对f()函数做任何的改变,因此调用f()的时候会自动调用父类的f()。并且f(s)在Derived1中也是可以使用的。
对于Derived2,它重定义了f()函数,而没有重定义f(s)函数,但是在这里却只能调用f()而不能调用f(s),即f(s)被隐藏了。
如果对Derived2修改一下,即重定义f()函数,也重定义f(s)函数,则两种都可以调用。
对于Derived3,它没有重定义基类中名为f的任何函数,而是通过修改返回值类型自己重新定义了一个名为f的函数,导致基类中的两个名为f的函数均不能被调用,即均被隐藏了。
对于Derived4,它没有重定义基类中名为f的任何函数,而是通过修改参数自己重新定义一个名为f的函数,导致基类中的两个名为f的函数均不能被调用,即均被隐藏了。
因此,可以得出一个结论:任何时候重新定义了基类中的一个重载函数,在新类之中所有其他的版本则被自动隐藏,除非在子类中全部重定义。
而对于虚函数的重写则有一点不同,即编译器不允许我们改变重定义过的函数的返回值类型(除了是将从基类引用或指针改为子类引用或指针),其它的则与重定义遵循一样的规则。这是为什么呢?在《Thinking in C++》上是这么说的:“因为编译器必须保证我们能够动态地通过基类调用函数,并且如果基类希望f()返回一个int值,则f()的派生类版本必须保持约定,否则将会出问题”。
- 重温《C++ Primer》笔记五 类定义中成员函数的名字隐藏(虚函数与非虚函数)
- !!!!!!!!!!!!!!!!C++:派生类中重定义基类的成员函数与虚函数区别在哪里?
- c++(成员函数的)重载、覆盖与隐藏
- C++:成员函数实现在类定义中与在类定义外的区别
- 类中成员函数的重载、覆盖与隐藏[转]
- <C++>9.类成员函数的定义
- 重温《C++ Primer》笔记四 构造函数的初始化列表
- 重温《C++ Primer》笔记六 拷贝构造函数的存在
- C++类中成员函数的定义
- C++:成员函数的重载、覆盖与隐藏 、多态
- C++:成员函数的重载、覆盖与隐藏
- 重温C++ primer 之C++类中的static数据成员,static成员函数
- 类成员函数中重载/重写(覆盖)/重定义(隐藏)的区别
- C++函数名字的隐藏:重写、重载、重定义
- C++函数名字的隐藏:重写、重载、重定义
- 成员函数的隐藏
- 【C++】成员函数的重载,覆盖,隐藏
- C++中成员函数的重载、覆盖与隐藏
- 第二大的数
- Generic Programming and the STL笔记5--Iterator Classes
- 应用程序的代码混淆(打包)
- hdu 5207 Greatest Greatest Common Divisor(数论)
- android语音识别之科大讯飞语音API的使用
- 重温《C++ Primer》笔记五 类定义中成员函数的名字隐藏(虚函数与非虚函数)
- 物理引擎
- 编译中遇到的异常报错解决
- BADI查找方法
- 设置ListView中的分割线divider不顶边的方法
- TCP连接探测中的Keepalive 和心跳包
- 获取context的几种方式
- vc中nmake.exe cl.exe 的使用(与编译相关)
- android布局之android:orientation=""Incorrect line ending: found carriage return (\r) without correspond