class student
{
private:
int age;
public:
student();
student(int a) {age = a;}
~student() {};
friend student& operator+ (int left, student& s);
friend ostream& operator<< (ostream& o, student& s);
}
...
student& operator + (int left, student& s)
{
s.age += left;
return s;
}
ostream& operator<< (ostream& o, student& s)
{
o << s.age << endl;
}
int main (void)
{
student a (10);
cout << 14 + a ;
return 0;
}
所以我从上面的代码中得到两个问题。
为什么必须在return s;
函数中执行operator+ (int left, student& s)
?
为什么不能将返回类型设置为void
,因为您已经通过引用传递了student
个对象?
每当我在endl
之后放14 + a
时,我都会收到错误,我发现错误并且无法打印。我知道这与`operator&lt;&lt;'有关,但我不知道它的确切原因,你怎么防止这种情况发生?
答案 0 :(得分:6)
你为什么要做回报;在运算符+(int left,student&amp; s)函数中?
我必须说你对operator +
的定义很奇怪,因为它修改了右侧对象 - 而operator +
通常没有,并且按值返回一个新对象。
无论如何,operator +
通常不会返回void
,因此它允许链接,如:
14 + (16 + a)
但同样,operator +
不应该修改右侧对象。你可能想写一些像operator +=
这样的东西。请考虑更改operator +
。
似乎每当我在14 + a之后放入endl时都会出现错误,我发现错误并且无法打印。我知道这与`operator&lt;&lt;'有关,但我不知道它的确切原因,你怎么防止这种情况发生?
您的程序有未定义的行为,因为operator <<
的重载不会返回任何内容。您应该添加一个return语句:
ostream& operator<< (ostream& o, student const& s)
// ^^^^^
{
o << s.age << endl;
return o;
// ^^^^^^^^^ <== Without this, your program has undefined behavior.
// Value-returning functions MUST return a value (with
// the only exception of main())
}
另外,如上所述,您应该通过引用student
接受const
对象,因为operator <<
不会改变其状态(如果您不这样做) ,您无法将operator <<
与const
对象一起使用。
答案 1 :(得分:1)
关于1,您不必做任何事情。语言 对重载的操作没有任何限制 运营商。另一方面,可维护性和可读性 确实要求重载运算符以某种方式运行 相应的内置运算符。因此:
为名为的类型重载加法没有意义
student
,因为添加学生没有意义。 (关于
另一方面,你的班级student
看起来更像是一个
StudentAge
的抽象。)
添加(运算符+
)不修改其中任何一个
参数。几乎没有例外。在你的情况下(假设
StudentAge
,而不仅仅是Student
),我可以看到三个
运营商:StudentAge operator+( StudentAge const& lhs, int rhs
)
,StudentAge operator+( int lhs, StudentAge const& rhs )
,
最重要的是,StudentAge& StudentAge::operator+=( int rhs )
。
最后一个将更改this
,前两个应该
可能是在第三次超载方面实施的。
所有重载的加法运算符都应该返回
什么,因为这是内置运营商所做的。
operator+
返回一个新对象,operator+=
返回
对this
(return *this;
)的引用。再一次,永远。
其他任何事情都是滥用,只会让读者感到困惑。
关于你的第二个问题:你已经宣布了
operator<<
返回一些东西,然后实现它返回
一些东西。刚刚结束是不明确的行为(甚至
没有其他任何事情。)
答案 2 :(得分:0)
对于1),请考虑以下代码:
student aStudent = anotherStudent + aDifferentStudent;
这里,我们接受两个参数并返回一个值。这就是您需要返回类的实例的原因。您当前的实现不是执行operator +函数的标准方法,因为它修改了参数。考虑这里使用的字符串运算符:
std::string aString = "Hello" + " " + "World";
从右到左操作,“”和“World”是文字字符串,传递给函数,返回“World”,然后再与“Hello”一起传递给函数(因为你有2个)调用operator +方法)最终返回“Hello World”。你的实现不能这样做,因为A)函数参数没有被声明为const,而B)如果它们是,并且它做了一个const-cast来修改,你将试图修改一个字符串文字 - 未定义的行为。
字符串是人们期望运算符+重载如何工作的一个很好的例子,以避免破坏最小意外的主体。
至于你的&lt;&lt;和endl问题,原则上类似。你需要返回o实例。