为什么编译器没有显示错误当我有两个函数一个将基类和一个将派生类作为参数?

问题描述:

我有一个基类和从基类派生的派生类。每个人都有一个朋友功能,如下所示,它将超载operator+为什么编译器没有显示错误当我有两个函数一个将基类和一个将派生类作为参数?

#include <iostream> 

using namespace std; 

class base 
{ 
    private: 
     int x; 

    public: 
     base(int a) : x(a) 
     { 
     } 

     void printx() 
     { 
      cout << "x : " << x << endl; 
     } 

     friend void operator+(int data, base &obj); 
}; 

void operator+(int data, base &obj) 
{ 
    obj.x = data + obj.x; 
} 

class derived : public base 
{ 
    private: 
     int y; 

    public: 
     derived(int a, int b) : base(a), y(b) 
     { 
     } 

     void printy() 
     { 
      cout << "y : " << y << endl; 
     } 

     friend void operator+(int data, derived &obj); 
}; 

void operator+(int data, derived &obj) 
{ 
    operator+(data, obj); 
    obj.y = data + obj.y; 
} 

int main() 
{ 
    derived c(2, 3); 

    4 + c; 

    c.printx(); 
    c.printy(); 
} 

我以为编译器会因朋友函数而抛出错误。

void operator+(int data, base &obj) 
void operator+(int data, derived &obj) 

将基类对象作为参数的函数也可以采用派生类对象,因为基类是派生类的一部分。所以我认为编译器会显示错误,因为这两个函数都可以将派生类对象作为参数。但是这个程序工作正常。任何人都可以解释为什么编译器不显示错误?

+0

downvoter。请让我知道这个问题有什么问题。 – kadina

+0

也许是因为这个问题太简单了,只值几分钟的搜索? – iBug

+0

引发异常。显示错误。不要滥用标准术语。 – EJP

简单的回答:这两个函数不冲突,因为它们没有相同的签名。

当您使用基础实例调用它时,它不适合派生类的引用,因此将调用operator+(int, base&)

当您使用派生实例调用一个实例时,基本函数需要隐式转换,而派生函数不需要,因此operator+(int, derived&)将被调用。

参考:功能Overload Resolution,见可行函数最佳可行函数部分。

1)有F1,其隐式转换比为F2的该参数相应的隐式转换更好的至少有一个参数

当然no的隐式转换是多于一个的“更好”的隐式转换,那么operator+(int, base&)将不会被调用为一个devired对象。

对于4 + c;,overload resolution会尝试选择最好的一个; operator+(int data, derived &obj)完全匹配,operator+(int data, base &obj)需要隐式转换(从derivedbase),然后选择operator+(int data, derived &obj),这里没有模糊性错误。