重载运算符<<和operator +导致错误

时间:2013-05-16 07:59:35

标签: c++ operator-overloading

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;
}

所以我从上面的代码中得到两个问题。

  1. 为什么必须在return s;函数中执行operator+ (int left, student& s)? 为什么不能将返回类型设置为void,因为您已经通过引用传递了student个对象?

  2. 每当我在endl之后放14 + a时,我都会收到错误,我发现错误并且无法打印。我知道这与`operator&lt;&lt;'有关,但我不知道它的确切原因,你怎么防止这种情况发生?

3 个答案:

答案 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+=返回 对thisreturn *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实例。