码迷,mamicode.com
首页 > 其他好文 > 详细

条款33:避免隐藏继承而来的名称

时间:2015-05-24 10:08:43      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:

• 此例中混合了纯虚函数、虚函数、非虚函数等,只是为了强调隐藏的是继承而来的名字,至于名字代表的是什么并不重要,即使enum、nested class、typedef也不例外。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Base
 6 {
 7 public:
 8     virtual void mf1() = 0;
 9     virtual void mf1(int);
10     virtual void mf2();
11     void mf3();
12     void mf3(double);
13 
14 private:
15     int x;
16 };
17 
18 class Derived : public Base
19 {
20 public:
21     virtual void mf1();
22     void mf3();
23     void mf4();
24 };
25 int main()
26 {
27     Derived d;
28     int x;
29     d.mf1();    // 正确:调用Derived::mf1
30     d.mf1(x);   // 错误:因为Derived::mf1隐藏了Base::mf1
31     d.mf2();    // 正确:调用Base::mf2
32     d.mf3();    // 正确:调用Derived::mf3
33     d.mf3(x);   // 错误:因为Derived::mf3隐藏了Base::mf3
34 
35     return 0;
36 }

说明:Base类中的任何同名函数都会被Derived类中同名函数隐藏掉,不论函数是否为虚函数,这些机制的是为了防止从基类中继承重载函数。实际上如果你使用public继承而又不继承基类中的重载函数,那就违反了is-a关系。

 

• 如果确实想使用基类Base中同名的函数,那么就需要使用using Base::名字

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Base
 6 {
 7 public:
 8     virtual void mf1() = 0;
 9     virtual void mf1(int);
10     virtual void mf2();
11     void mf3();
12     void mf3(double);
13 
14 private:
15     int x;
16 };
17 
18 class Derived : public Base
19 {
20 public:
21     using Base::mf1;    // 让Base类中名为mf1和mf3的所有东西在
22     using Base::mf3;    // 派生类Derived中可见
23     virtual void mf1();
24     void mf3();
25     void mf4();
26 };
27 
28 int main()
29 {
30     Derived d;
31     int x;
32     d.mf1();    // 正确:调用Derived::mf1
33     d.mf1(x);   // 正确:调用Base::mf1(int)
34     d.mf2();    // 正确:调用Base::mf2
35     d.mf3();    // 正确:调用Derived::mf3
36     d.mf3(x);   // 正确:调用Base::mf3(double)
37 
38     return 0;
39 }

 

• 在public继承下,不想继承Base中的所有函数是不可能的。考虑private继承下的一个例子:Derived以private方式继承Base,其想唯一继承的是mf1的无参版本,如果使用using,那么重载版本也会被继承。以下描述了一个简单的转交函数(forwarding function):

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Base
 6 {
 7 public:
 8     virtual void mf1() = 0;
 9     virtual void mf1(int);
10     virtual void mf2();
11     void mf3();
12     void mf3(double);
13 
14 private:
15     int x;
16 };
17 
18 class Derived : private Base
19 {
20 public:
21     virtual void mf1()  // forwarding function
22     {
23         Base::mf1();
24     }
25     void mf3();
26     void mf4();
27 };
28 
29 int main()
30 {
31     Derived d;
32     int x;
33     d.mf1();    // 正确:调用Derived::mf1
34 
35     return 0;
36 }

总结:Derived中的名称会隐藏Base中的名称,不论是什么类型,而使用using声明或者转交函数可以解决这个问题。

 

条款33:避免隐藏继承而来的名称

标签:

原文地址:http://www.cnblogs.com/benxintuzi/p/4525376.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!