C++ 当多态和重载混合

只有多态

#include <iostream>
class Base {
public:
  virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
  //virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
  virtual ~Base() {}
};

class Derived : public Base {
public:
  //using Base::f; // (2)
  void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};

int main(int, char **) {
  Derived d;		
  d.f(21);		//Derived::Double!
  d.f(1.1);		//Derived::Double!
  Base* p = &d;
  p->f(21);		//Derived::Double!
  p->f(0.1);	//Derived::Double!
  return 0;
}

这是一个典型的多态的例子

继承默认不能重载父类函数

如果注释(1),代码变为:

#include <iostream>
class Base {
public:
  virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
  virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
  virtual ~Base() {}
};

class Derived : public Base {
public:
  //using Base::f; // (2)
  void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};

int main(int, char **) {
  Derived d;		
  d.f(21);		//Derived::Double!
  d.f(1.1);		//Derived::Double!
  Base* p = &d;
  p->f(21);		//Base::Int!
  p->f(0.1);	//Derived::Double!
  return 0;
}

前两个输出结果是因为,此时派生类的 f(double) 遮蔽(hide)了基类的两个函数。这是因为编译器在基类的作用域发现了一个 f,就不会向上沿着继承树寻找重载。

后两个输出结果是因为此时多态任然存在,此时虚函数表为:

BaseDerived
Base::f(double)Derived::f(double)
Base::f(int)Base::f(int)

因此p->f(21)会调用父类的函数Base::f(int)

如果我们把 (3) 也注释了,代码将变为:

#include <iostream>
class Base {
public:
  virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
  virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
  virtual ~Base() {}
};

class Derived : public Base {
public:
  // using Base::f; // (2)
  // void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};

int main(int, char **) {
  Derived d;
  d.f(21);		//Base::Int!
  d.f(1.1);		//Base::Double!
  Base* p = &d;
  p->f(21);		//Base::Int!
  p->f(0.1);	//Base::Double!
  return 0;
}

这是因为子类没有 f 函数,编译器就会向上寻找父类,发现父类有 2 个 f,就构成了重载

如果想要重载父类函数,有两种办法:

手动重载

class Base {
public:
  virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
  virtual void f(int) { std::cout << "Base::Int!" << std::endl; }
  virtual ~Base() {}
};

class Derived : public Base {
public:
  void f(int a) { Base::f(a); }
  void f(double) { std::cout << "Derived::Double!" << std::endl; }
};

这很麻烦,后来 C++ 委员会增加了 using 关键词,如下:

using

#include <iostream>
class Base {
public:
  virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
  virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
  virtual ~Base() {}
};

class Derived : public Base {
public:
  using Base::f; // (2)
  void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};

int main(int, char **) {
  Derived d;		
  d.f(21);		//Base::Int!
  d.f(1.1);		//Derived::Double!
  Base* p = &d;
  p->f(21);		//Base::Int!
  p->f(0.1);	//Derived::Double!
  return 0;
}

using 相当于将父类的函数名 f 引入到了派生类。此时就可以正常重载了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值