繁体   English   中英

运算符<<:std :: cout << i <<(i << 1);

[英]operator << : std::cout << i << (i << 1);

我在一行中使用了流运算符<<和位移运算符<<。 我有点困惑,为什么代码A)与代码B)不会产生相同的输出?

一种)

int i = 4;  
std::cout << i << " " << (i << 1) << std::endl;   //4 8

B)

myint m = 4;
std::cout << m << " " << (m << 1) << std::endl;   //8 8

类myint:

class myint {
    int i;
public:
    myint(int ii) {
        i = ii;
    }
    inline myint operator <<(int n){
        i = i << n;
        return *this;
    }
    inline operator int(){
        return i;
    }
};

提前致谢
哎呀

您的第二个示例是未定义的行为。

您已经在myint类上定义了<<操作符,就好像它实际上是<<= 当您执行i << 1 ,在价值i不被修改,但是当你执行m << 1 ,在价值m 修改。

在C ++中,对变量进行读写(或多次写入)而没有中间顺序点是不确定的行为,就其参数而言,函数调用和运算符都不是中间点。 代码是否不确定

std::cout << m << " " << (m << 1) << std::endl;  

将在mm << 1更新之前或之后输出第一个m 实际上,您的代码可能会做一些完全奇怪的事情,或者崩溃。 未定义的行为可能导致任何事情,因此请避免使用。

myint定义<<操作符的正确方法myint是:

myint operator<< (int n) const
{
   return myint(this->i << n);
}

this->不是严格必需的,只是我重载运算符时的样式)

因为int << X返回一个新的int。 myint << X修改当前的myint。 您的myint <<运算符应固定为前者。

首先获得8的原因是,显然在实现中首先调用m << 1。 该实现可以自由地以任何顺序进行操作。

您的<<运算符实际上是<< =运算符。 如果您用

std::cout << i << " " << (i <<= 1) << std::endl;   //8 8

你应该得到8 8。

由于mmyInt第二个示例可以重写为:

std::cout << m << " " << (m.operator<<( 1)) << std::endl; 

评价的子表达式的顺序m(m.operator<<( 1))是不确定的,所以没有说法,其中“ m ”,你会得到第1'表达的是m被使用(这是一个简单的m表达式)。 因此,您可能会得到“ 4 8”的结果,也可能会得到“ 8 8”。

请注意,该语句不会导致未定义的行为,因为在m修改与“读取”之间存在序列点(至少一个函数调用)。 但是未指定子表达式的求值顺序,因此尽管编译器必须生成结果(它不会崩溃-至少不会合法崩溃),但没有说应该生成两个可能结果中的哪一个。

因此,该语句与具有未定义行为的语句一样有用,也就是说它不是很有用。

那么(m << 1)在m之前被求值,因此m已经持有8,因为在运算符<<中,您覆盖了自己的值。

这是您的错误行为,operator <<应该是const,不能更改您的对象。

因为myint的<<操作符会修改其lhs。 因此,在计算m << 1 ,m实际上将具有值8(而i << 1仅返回8,但不使i等于8)。 由于未指定m<<1是否在cout << m之前执行(因为未指定函数或运算符的参数的评估顺序),因此未指定输出是8 8还是4 8

C ++语言未定义运算符的求值顺序。 它仅定义了它们的关联性。

由于您的结果取决于表达式中何时对operator<<函数进行求值,因此结果是不确定的。

代数operator $函数应始终为const并返回一个新对象:

inline myint operator <<(int n) const { // ensure that "this" doesn't change
    return i << n; // implicit conversion: call myint::myint(int)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM