代码之家  ›  专栏  ›  技术社区  ›  OlimilOops

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

c++
  •  1
  • OlimilOops  · 技术社区  · 14 年前

    我使用stream操作符<&书信电报;以及位移位运算符<&书信电报;在一条线上。 我有点困惑,为什么代码a)不能产生与代码B)相同的输出?

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

    (二)

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

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

    提前谢谢

    7 回复  |  直到 14 年前
        1
  •  8
  •   Tyler McHenry    14 年前

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

    您已经定义了 << myint 上课的时候好像 <<= . 当你执行 i << 1 ,中的值 i 不是修改,而是在执行时 m << 1 ,中的值 m 被改进的。

    在C++中,对没有变量的序列点进行读取和写入(或不止一次写入)是不确定的行为,函数调用和运算符不属于它们的参数。代码是否

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

    将输出第一个 之前还是之后 m<&书信电报;1 . 事实上,您的代码可能会做一些完全奇怪的事情,或者崩溃。未定义的行为可以导致任何事情,所以要避免它。

    << 操作员 粘菌 是:

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

    this-> 不是绝对必要的,只是我过载时的风格)

        2
  •  5
  •   Edward Strange    14 年前

    因为int<&书信电报;X返回一个新的int.myint<&书信电报;X修改当前myint。您的myint<&书信电报;操作员应固定做前者。

        3
  •  2
  •   Neil G    14 年前

    您的<&书信电报;操作员实际上是<<=接线员。如果你用

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

    你应该得到8分。

        4
  •  2
  •   Michael Burr    14 年前

    自从 m 是一个 myInt 您的第二个示例可以重写为:

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

    子表达式的求值顺序 (m.operator<<( 1)) “你会得到第一个表达 用于(这是一个简单的

    请注意 不会导致未定义的行为 因为在

    所以这个语句和一个有未定义行为的语句一样有用,也就是说它不是很有用。

        5
  •  1
  •   ypnos    14 年前

    井(m<&书信电报;1) 是在m之前计算的,因此m已经包含8,就像在操作符中一样<&书信电报;你改写了自己的价值观。

    这是你的错误行为,接线员<&书信电报;应该是常量而不是改变你的对象。

        6
  •  0
  •   sepp2k    14 年前

    因为 << m << 1 ,m将实际具有值8(而 i << 1 只返回8,但不使i等于8)。因为没有规定 m<<1 在之前执行 cout << m (因为没有指定函数或运算符的参数的求值顺序),所以没有指定是否将输出 8 8 4 8 .

        7
  •  0
  •   Potatoswatter R. Martinho Fernandes    14 年前

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