我正在尝试应用我在下面的C++类中学到的一些运算符加载概念。
#include<iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int, int);
Point operator+(const Point&);
friend istream& operator>>(istream& in, Point&);
friend ostream& operator<<(ostream& out, Point&);
Point operator=(const Point&);
};
Point::Point(int x = 0, int y = 0)
:x(x), y(y){}
Point Point::operator+(const Point& p)
{
int r1, r2;
r1 = x + p.x;
r2 = y + p.y;
return Point(r1, r2);
}
Point Point::operator=(const Point& p)
{
this->x = p.x;
this->y = p.y;
return *this;
}
istream& operator>>(istream& in, Point& p)
{
char openParenthesis, closeParenthesis, comma;
cout << "Enter data in the format (1,2): ";
in >> openParenthesis >> p.x >> comma >> p.y >> closeParenthesis;
return in;
}
ostream& operator<<(ostream& out, Point& p)
{
out << "(" << p.x << "," << p.y << ")";
return out;
}
int main()
{
Point a, b;
cin >> a >> b;
cout << "a + b is: " << a + b << endl;
return 0;
}
该代码在Visual Studio上编译并运行良好。但是当我尝试使用 gcc 在 Linux 上编译它时,它会抛出一长串错误,如下所示:
在/usr/include/c++/4.8/iostream:39:0 包含的文件中, 来自 optr_overload.cpp:1:/usr/include/c++/4.8/ostream:471:5: 注意: 模板 std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT) 操作员<<(basic_ostream<_CharT,_Traits>__out,_CharT __c) ^/usr/include/c++/4.8/ostream:471:5: 注意:模板参数推导/替换失败: optr_overload.cpp:53:30: 注意:
推断参数"_CharT"("字符"和"点")的冲突类型 cout <<"a + b is: " <<a + b <<endl;
我知道问题出在我将"a + b"传递给重载二进制流插入运算符的行上,该运算符仅接收对一个 Point 对象的引用作为参数。但是我不知道如何修复代码,除了将"a + b"分配给第三个对象并将该单个对象作为参数传递给"<<"。有人可以向我解释一下 gcc 编译我的代码到底需要做什么,最好不涉及使用额外的占位符对象。
用a + b
计算的值是一个临时对象,因此不能作为Point&
传递给operator<<
;该语言只允许临时作为const Point&
传递。只需更改输出运算符的声明即可接受const Point&
。
允许将临时结果作为非常量引用传递是旧版 VC++ 中的一个已知错误。
你几乎一切都是对的,但你的ostream& operator<<()
应该通过常量引用来获取 Point:
friend ostream& operator<<(ostream& out, const Point&);
这应该可以解决您的问题。
(不用担心Point::x
和Point::y
是私密的,你已经宣布你的operator<<
是朋友。