我使用朋友函数为基类和派生类重载了'+'运算符,如下所示。
#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)
{
cout << "in friend base" << endl;
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)
{
cout << "in friend derived" << endl;
operator+(data, obj.base);
obj.y = data + obj.y;
cout << "y in friend : " << obj.y << endl;
}
int main()
{
derived c(2, 3);
4 + c;
c.printx();
c.printy();
}
但这会产生编译错误,如下所示
inoverload+.cpp: In function ‘void operator+(int, derived&)’:
inoverload+.cpp:51:25: error: invalid use of ‘base::base’
operator+(data, obj.base);
以下程序已成功编译。
#include <iostream>
using namespace std;
class base
{
public:
int x;
base(int a) : x(a)
{
}
};
class d1 : public base
{
public:
d1(int a) : base(a)
{
}
};
class d2 : public base
{
public:
d2(int a) : base(a)
{
}
};
class derived : public d1, public d2
{
public:
derived(int a) : d1(a), d2(a)
{
}
};
int main()
{
derived obj(2);
cout << obj.d1::x << endl;
}
任何人都可以解释为什么我无法在第一个程序中使用派生类对象访问基础部分,因为我可以在同一个程序中执行相同操作。
注意:我已经尝试使用强制转换功能。但我的问题是,使用obj.base访问base是不正确的,这在第二个程序obj.d1 :: x中是否正确?
答案 0 :(得分:4)
点运算符用于成员访问。但base
中没有derived
成员,因此obj.base
格式不正确。要从派生对象显式获取基类引用,需要强制转换:
operator+(data, static_cast<base&>(obj));
在第二个程序obj.d1::x
中,我们无法访问成员 d1
。它访问成员x
。但是,为了解决歧义,C ++允许使用范围解析运算符消除歧义在哪个唯一的基类子对象中找到该成员。
答案 1 :(得分:2)
行operator+(data, obj.base);
表示obj
有一个名为base
的成员,这不是真的。派生对象的基本部分未表示为成员。
要强制重载以将您的对象视为它的基本类型,您可以将其视为对其基类的引用。然后编译器必须将其视为它的类型是该函数调用的基本类型。请尝试以下方法:
void operator+(int data, derived &obj)
{
cout << "in friend derived" << endl;
operator+(data, static_cast<base&>(obj)); // Cast happens here
obj.y = data + obj.y;
cout << "y in friend : " << obj.y << endl;
}