分享

子类中using引入基类函数时需要注意的情况

 verychen 2010-12-01
子类中using引入基类函数时需要注意的情况 收藏
子类中using引入基类函数时需要注意的情况
class base{
public:
 void test(){
  cout << "base::test()" << endl;
 }
 void test(int){
  cout << "base::test(int)" << endl;
 }
};
class derived : public base{
public:
 void test(){
  cout << "derived::test()" << endl;
 }
};
此时derived::test()会隐藏(hide)父类中的两个test重载函数(base::test()和base::test(int)),因此我们为子类中加上一个using声明:
class derived : public base{
public:
 void test(){
  cout << "derived::test()" << endl;
 }
 using base::test;//此声明放在test前面和后面效果都一样
};
现在会不会出现下面所述的情况呢?
---------------------------------------------------------------------------------------------------------------
既然using base::test将父类中的两个test函数都引入子类,则子类中就相当于有了一个void test()函数,所以我们在子类中重新定义的void test()函数将会和从父类中引入的void test()函数发生冲突,进而出现“重定义”错误。
---------------------------------------------------------------------------------------------------------------
答案是:不会!
此时,子类中重新定义的void test()函数将“顶替”从父类中引入的void test()函数。
(PS:从父类中引入的另外一个void test(int)函数则没有发生变化(仍然是父类中的函数实现)。)
类似的另外一种情况如下,此时加入了virtual:
class base{
public:
 virtual void test(){
  cout << "base::test()" << endl;
 }
 virtual void test(double){
  cout << "base::test(double)" << endl;
 }
 void test(int){
  cout << "base::test(int)" << endl;
 }
};
class derived : public base{
public:
 void test(){
  cout << "derived::test()" << endl;
 }
};
此时derived::test()虽然重写(override)了base::test(),但是同时也隐藏(hide)父类中的两个test重载函数(一个virtual函数base::test(double)和一个nonvirtual函数base::test(int))。现在,我们为子类中加上一个using声明:
class derived : public base{
public:
 void test(){
  cout << "derived::test()" << endl;
 }
 using base::test;//此声明放在test前面和后面效果都一样
};
与上面的类似,此时derived::test()“仍然重写”了父类的base::test(),并且与父类中的base::test(double)和base::test(int)[在子类的域]中形成重载集合。

最后,留一个思考题目,如下:
class base{
public:
 virtual void test(){
  cout << "base::test()" << endl;
 }
 virtual void test(double){
  cout << "base::test(double)" << endl;
 }
 void test(int){
  cout << "base::test(int)" << endl;
 }
};
class derived : public base{
public:
 void test(){
  cout << "derived::test()" << endl;
 }
 //using base::test;
};
class A : public derived{
public:
 void test(double){
  cout << "A::test(double)" << endl;
 }
};
int main(int argc, char **argv){
 base *pb = new A;
 pb->test(2.4);
 return 0;
}
问题:derived中的using base::test加上与否,对程序的结果有什么影响?
答:没有影响。(关键点:名字解析是编译时期的事情,而virtual函数动态绑定是运行时期的事情。)
(PS:但是将main函数改成“derived *pd = new A; pd->test(2.4);”,则有区别了:如果将using base::test去掉,则编译失败。)
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/OOPhaisky/archive/2007/01/24/1492560.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多