首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重载operator<<和operator+导致错误

重载operator<<和operator+导致错误
EN

Stack Overflow用户
提问于 2013-05-16 07:59:34
回答 3查看 94关注 0票数 2
代码语言:javascript
复制
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之后时,我似乎得到了一个错误,我捕捉到一个错误,并且它不打印。我知道这与“操作符<<”有关,但我不知道其确切原因,以及如何防止这种情况发生?
EN

回答 3

Stack Overflow用户

发布于 2013-05-16 08:04:15

为什么必须在operator+ (int左侧,student& s)函数中返回s;?

我必须说,您对operator +的定义很奇怪,因为它修改了右边的对象--而operator +通常不会修改,并且按值返回一个新的对象。

无论如何,operator +通常不会返回void以便允许链接,如下所示:

代码语言:javascript
复制
14 + (16 + a)

但是,operator +不应该修改右侧对象。您可能打算编写类似于operator +=的东西。考虑更改operator +的定义。

似乎每当我把endl放在14 + a之后,我就会得到一个错误,我会捕捉到一个错误,并且它不会打印。我知道这与“操作符<<”有关,但我不知道其确切原因,以及如何防止这种情况发生?

您的程序有未定义的行为,因为您的operator <<重载不返回任何内容。您应该添加一条返回语句:

代码语言:javascript
复制
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())
}

此外,正如上面所做的那样,您应该通过引用const来接受const对象,因为operator <<不会改变它的状态(如果没有这样做,您就不能在const对象中使用operator <<

票数 6
EN

Stack Overflow用户

发布于 2013-05-16 08:22:57

关于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<<返回某些内容,所以要实现它来返回某些内容。刚从终点掉下来就是未定义的行为(甚至没有任何其他的后续行为)。

票数 1
EN

Stack Overflow用户

发布于 2013-05-16 08:12:48

对于1),请考虑以下代码:

代码语言:javascript
复制
student aStudent = anotherStudent + aDifferentStudent;

这里,我们使用两个参数并返回一个值。这就是为什么您需要返回类的一个实例。当前的实现不是执行operator+函数的标准方法,因为它修改了参数。考虑一下这里使用的字符串operator+:

代码语言:javascript
复制
std::string aString = "Hello" + " " + "World";

从右到左操作,“”和"World“是文字字符串,传递给函数,函数返回”World",然后将"Hello“与"Hello”一起传递给函数(因为您有两个对operator+方法的调用),最终返回“Hello”。您的实现不能这样做,因为A)函数参数没有声明const,而B)如果它们声明为const,并且它执行了const-cast来修改,那么您将尝试修改字符串文本-未定义的行为。

String是一个很好的例子,说明人们期望operator+重载如何工作,以避免破坏最小惊喜的原则。

至于您的<<和endl问题,这在原则上是类似的。您需要返回o实例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16581953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档