分享
 
 
 

如何在派生类中的隐藏基类的虚拟重载函数?

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

如何在派生类中的隐藏基类的虚拟重载函数?

作者:northtibet

我创建了一个类,基类中有虚拟重载函数。我想在派生类中改写基类中的虚拟重载函数。代码如下:

#include <iostream.h>

class B {

private:

int nNumber;

public:

virtual void test() {

cout << "B::test()\n"; }

virtual void test(int x) {

nNumber = x; // 将传入的参数赋值给私有成员

cout << "B::test(int x)\n";

}

};

class D : public B {

public:

//test(void) 隐藏 B::test(int)

virtual void test() {

cout << "D::test()\n";

}

};

void main(int argc, char* argv[])

{

D d; // 派生类的实例

d.test(); // OK

d.test(17); // 产生编译错误的代码行

}

基类中有两个重载的test函数。当我在派生类中改写其中的一个函数时,我觉得另外一个应该在派生类中继承,但编译时出现一下错误信息:

... C2660 : ''test'' :function does not take 1 parameters

在不放弃多态行为的情况下,我能不能同时重载和改写某个函数?

许多C++程序员都对这个问题感到困惑,为了解开这个惑点,有两个概念你必须要了然于心。一个是重载,一个是名字空间。从重载的视角看,你可能觉得C++应该按照你所想象的方式工作;也就是如果派生类只修改其中的一个重载函数的行为,那么另外一个应该按照通常的方式被继承。但从名字空间的角度看,当C++试图解决某个符号名时,它以由近到远的顺序进行搜索,它首先找本地变量,然后是类成员名,接着是基类名,全局变量……。一旦编译器解析了名字,它便终止解析过程。如果在不同的名字空间范围碰到同一个符号名,那么它便没有了主意。在你的代码中,一旦编译器确定名字"test"出现在类D中,那么它的名字空间就为类D。不论你调用不带参数的test也好,还是调用带一个整型参数的test(17)也好,编译器都是遵循准这个规则来解决名字问题。对于有整型参数的test(int x)函数,一旦编译器确定函数名test生存在类D中,它便终止范围探查,然后查找与参数匹配的函数。由于它没有在类D中找到带整型参数的函数,所以报错。此时编译器认为函数D::test(void)隐藏了函数B::test(int)。你可能会问,为什么要按这种方式处理?问得好。想找到答案,请参考Bjarne Stroustrup 的C++注释参考手册(Section 13.1)。简单地说,在类层次深处搜索与某个签名匹配的重载函数比不搜索更可能导致混乱。

那么如何解决上面出现的问题呢?很容易。只要在派生类中创建另一个显式调用基类的test函数即可,如:

class D : public B {

public:

virtual void test(int x) { B::test(x); }

……

};

这样,D就有了两个test函数,问题也解决了。

其实这个问题还有另外一个解法:那就是在派生类中使用"using"关键字。如:

class D : public B {

public:

using B::test;

// 改写test

virtual void test() {

cout << "D::test()\n";

}

};

这个关键字将B::test带入类D中。它的优点是当类B扩展更多的test重载函数时,你不用再去重写类D的代码。这样省了很多事。只要你使用using关键字,那么就意味着所有重载的B::test函数都进入类D并且得到继承。这种特性可能对于某些人来说是优点,而对于另外一些人来说是缺点,依赖于你要做什么事情。如果你想要向类D的用户隐藏某些test函数,则可以用第一种方法(显式调用基类),或者让你想要隐藏的函数成为private 或 protected类型。如果你读过Scott的书《Effective C++》,还可以用第二种方法利用using关键字巧妙地保证基类的私隐。

class B {

public:

func1();

func2(double d);

virtual test();

virtual test(int x);

};

// D 从B中秘密派生

class D : private B {

public:

// 让所有 B::test 函数为 public类型

using B::test;

};

显然,当希望完全隐藏类B时,这个方法很有用,但如果想要公开B中的个别函数,则这个方法就不是那么好了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有