为什么重载在继承类中不工作?

 
这个问题(非常常见)往往出现于这样的例子中:
 
  1. #include<iostream>
  2.     using namespace std;
  3.     class B {
  4.     public:
  5.         int f(int i) { cout << "f(int): "return i+1; }
  6.         // ...
  7.     };
  8.     class D : public B {
  9.     public:
  10.         double f(double d) { cout << "f(double): "return d+1.3; }
  11.         // ...
  12.     };
  13.     int main()
  14.     {
  15.         D* pd = new D;
  16.         cout << pd->f(2) << '/n';
  17.         cout << pd->f(2.3) << '/n';
  18.     }
 
它输出的结果是:
     f(double): 3.3
    f(double): 3.6
 而不是象有些人猜想的那样:
     f(int): 3
    f(double): 3.6
 换句话说,在BD之间并没有发生重载的解析。编译器在D的区域内寻找,找到了一个函数double f(double),并执行了它。它永远不会涉及(被封装的)B的区域。在C++中,没有跨越区域的重载——对于这条规则,继承类也不例外。更多的细节,参见C++语言的设计和演变》和《C++程序设计语言》。
 但是,如果我需要在基类和继承类之间建立一组重载的f()函数呢?很简单,使用using声明:
    class D : public B {
    public:
        using B::f; // make every f from B available
        double f(double d) { cout << "f(double): "; return d+1.3; }
        // ...
    };
 进行这个修改之后,输出结果将是:
     f(int): 3
    f(double): 3.6
 
这样,在Bf()Df()之间,重载确实实现了,并且选择了一个最合适的f()进行调用。
这就是传说中的隐藏
 
 
什么是函数对象(function object)?
顾名思义,就是在某种方式上表现得象一个函数的对象。典型地,它是指一个类的实例,这个类定义了应用操作符operator()。
 
函数对象是比函数更加通用的概念,因为函数对象可以定义跨越多次调用的可持久的部分(类似静态局部变量),同时又能够从对象的外面进行初始化和检查(和静态局部变量不同)。例如:
 
class Sum {
    int val;
public:
    Sum(int i) :val(i) { }
    operator int() const { return val; }        // 取得值
 
    int operator()(int i) { return val+=i; }    // 应用
};
 void f(vector v)
{
    Sum s = 0;  // initial value 0
    s = for_each(v.begin(), v.end(), s);    // 求所有元素的和
    cout << "the sum is " << s << "/n";
   
    //或者甚至:
    cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "/n";
}
 
注意一个拥有应用操作符的函数对象可以被完美地内联化(inline),因为它没有涉及到任何指针,后者可能导致拒绝优化。与之形成对比的是,现有的优化器几乎不能(或者完全不能?)将一个通过函数指针的调用内联化。
 在标准库中,函数对象被广泛地使用以获得弹性。
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值