试题:两个基类有同名的虚函数要实现, 怎么办?
来源:互联网 发布:mac 查看照片拍摄日期 编辑:程序博客网 时间:2024/06/14 18:25
有两个类A, B, 它们可能是别人实现的(或是别人提供的库中的类), 很复杂且已经在用, 你不能修改他们, 你想写一个类C同时具有这两个类的特性, 因为自己实现它代价实在是太大, 所以你想到用C继承A, B以达到效果, 但是有一个问题, A, B具有一个同名的虚函数, 你在C中怎么重新实现这个虚函数呢? 先看下面的代码:
#include <string>#include <iostream>using namespace std;class ChineseName{public: virtual string getname() { return string(); }};class EnglishName{public: virtual string getname() { return string(); }};class Name : public ChineseName, public EnglishName{public: virtual string getname() { return string("chinese or english name? I donot know"); }};int main(){ Name n; ChineseName & c = n; EnglishName & e = n; cout << n.getname() << endl; cout << c.getname() << endl; cout << e.getname() << endl; return 0;}
三个输出都是一样的, 可是我怎么才能在c.getname()中输出中文名, e.getname()中输出英文名呢, 最根本的问题是我只能在Name中实现一个getname(), 但是它却被要求有两个功能, 分别输出中文名和英文名, 这着实没办法
"计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决",现在我们就通过增加两个中间类来试试
我们用两个抽象类来分别继承ChinessName和EnglishName, 它们分别重新实现getname(), getname()的实现方式相同, 都是通过NVI手法来做的(尽管getname()不是non-virtual函数), 它们分别调用两个非同名的纯虚函数, 然后再让Name继承这两个中间类, 具体实现看代码:
#include <string>#include <iostream>using namespace std;class ChineseName{public: virtual string getname() { return string(); }};class EnglishName{public: virtual string getname() { return string(); }};class ICName : public ChineseName{public: virtual string getname() { return getChineseName(); }private: virtual string getChineseName() = 0;};class IEName : public EnglishName{public: virtual string getname() { return getEnglishName(); }private: virtual string getEnglishName() = 0;};class Name : public ICName, public IEName{private: virtual string getChineseName() { return string("二斗墨汁"); } virtual string getEnglishName() { return string("Adward Ink"); }};int main(){ Name n; ChineseName & c = n; EnglishName & e = n;// cout << n.getname() << endl; cout << c.getname() << endl; cout << e.getname() << endl; return 0;}
上面的代码运行可以分别得到中文名和英文名, 但你也应该看到这句注释掉的代码: cout << n.getname() << endl; 是的, 它不能通过编译, 它会产生二义性, 因为它不知道调用的是从ICName还是从IEName继承下来的getname(), 但为什么第一份代码又可以呢? 其实我当初也以为会产生二义, 谁知没有, 不过从测试上分析, 可知: 一份getname()已经重写了两个基类的getname()的实现
如上我们可以用Name对象直接调用ChineseName和EnglishName中所有除getname()以为的功能接口, 如果我们想分别想得到中文名和英文名怎么办? 方法一同上代码, 先转化为对应基类的引用再调用getname(), 方法二把getChineseName()和getEnglishName()改成公有的, 直接调用这两个函数
第二份代码的实现, 得助于从网上得来的一份华为学习资料(几年前看资料学过来的技术, 原资料也被遗弃了), 感谢华为
- 试题:两个基类有同名的虚函数要实现, 怎么办?
- 一个类如何实现两个接口中同名同参数不同返回值的函数
- 函数的同名变量实现可变函数
- JS实现子类调用父类的同名函数函数
- 实现宏与函数同名
- 假设派生类继承自两个基类,而两个基类中有同名虚函数,问虚表
- 继承TextView要实现的3个同名不同参构造函数分别是什么意思?
- C#实现根据字符串调用同名的函数
- 发现和记录--页面中定义两个同名的JS函数,调用会是什么结果
- 同名函数的调用问题
- JavaScript同名函数的调用
- Cookie出现两个同名Key的问题
- 当有多个同名的action可怎么办呢?
- 重定义不同基类的同名虚函数
- C++ 同名隐藏、覆盖,虚函数 的详解和对比
- js中同名函数和同名变量的执行问题
- Java的同名属性、同名普通函数、同名静态函数,是否被覆盖
- C++ 实现 根据字符串 调用同名函数
- 苹果新专利:让电源适配器记住密码
- Product line
- 动态规划 杭电1176
- 线程 (Handler、Looper、MessageQueue和Thread的理解)
- 工厂模式
- 试题:两个基类有同名的虚函数要实现, 怎么办?
- 一次带大字段表记录暴增(LOBSEGMENT)引发的悲剧
- 第一次写博客
- 移动平台WEB前端开发技巧汇总
- vs 2008 不能切换到设计视图的解决办法
- Linux下清空系统cache缓存
- Top K算法详细解析---百度面试
- exe 视频文件破解
- 人生·工作的结果 = 思维方式 × 热情 × 能力