Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建C++;integer类的作用与integer类型完全相同_C++_Operator Overloading - Fatal编程技术网

C++ 创建C++;integer类的作用与integer类型完全相同

C++ 创建C++;integer类的作用与integer类型完全相同,c++,operator-overloading,C++,Operator Overloading,我几天前看到的一个小问题,在采访中问我的朋友 最初的面试问题是:“以下代码的输出是什么?” 正确答案是((2+2)+1)+1=6,即在分配之前,但在添加之后,后增量应用两次 然后我想创建一个简单的类,其中包含一个整数和重载操作符+()和操作符++(int),以便在日志中查看操作符执行的确切顺序 这就是我得到的: class A { public: A(int _data) : data(_data) { } A &operator=(const A& _rhs) { d

我几天前看到的一个小问题,在采访中问我的朋友

最初的面试问题是:“以下代码的输出是什么?”

正确答案是((2+2)+1)+1=6,即在分配之前,但在添加之后,后增量应用两次

然后我想创建一个简单的类,其中包含一个整数和重载操作符+()和操作符++(int),以便在日志中查看操作符执行的确切顺序

这就是我得到的:

class A
{
public:
A(int _data) : data(_data) { }

A &operator=(const A& _rhs)
{
    data = _rhs.data;
    cout<<" -- assign: "<<data<<endl;
}

A operator++(int _unused)
{
    A _tmp = data;
    data++;

    cout<<" -- post-increment: "<<data<<endl;
    return _tmp;
}

A operator+(const A &_rhs)
{
    A _tmp = data + _rhs.data;

    cout<<" -- addition: "<<data<<"+"<<_rhs.data<<endl;
    return _tmp;
}

inline operator int() const { return data; }

private:
    int data;
};
对于不太复杂的构造,例如(A _dt2=A++),它的作用应该是这样的,但运算符的执行顺序与整数类型不同

我想这可能是编译器特有的问题:

$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
所以,我有点迷路了:)

最初的面试问题是:“以下代码的输出是什么?”

正确答案是,因为您多次修改同一变量,其间没有序列点

C++03标准
§5[expr]p4

除非另有说明,否则未指定单个运算符的操作数和单个表达式的子表达式的求值顺序以及副作用发生的顺序


这可能无法回答您真正的问题,但即使您创建一个类似整数的类并重载
运算符++(int)
运算符+(常量&)
,情况也会类似。函数参数的求值顺序是未指定的,可以按照编译器喜欢的任何顺序进行,因此结果是未指定的。

实际上,您在早期犯了一个非常严重的错误

最初的面试问题是:“以下代码的输出是什么?”

这个问题的正确答案是“输出未定义”

通过在没有插入序列点的情况下修改和读取变量,您正在调用未定义的行为


更具体地说,在这种情况下,让您头疼的是
+
运算符的参数计算顺序没有定义;这在运算符和函数的一般情况下都是正确的,但有几个显著的例外,即短路逻辑运算符

正确答案是((2+2)+1)+1=6,即在分配之前,但在添加之后,后增量应用两次

这不是正确的答案:

除非另有说明,否则未指定单个运算符的操作数和单个表达式的子表达式的求值顺序以及副作用发生的顺序。在上一个序列点和下一个序列点之间,标量对象的存储值最多应通过表达式的计算修改一次。此外,只有在确定要存储的值时,才能访问先前的值。完整表达式子表达式的每个允许顺序应满足本段的要求 表达方式;否则行为未定义。
-ISO-IEC-14882


除了其他人已经指出的:孤立地把问题的标题取出来——“创建C++整数类,完全与整数整数类型完全相同”——我应该指出一个完全不同的原因,即它是<强>不可能< /强>

据我所知,不可能用类来模拟|&&运算符的快捷方式行为,即无论发生什么情况,都将对操作数的两侧进行求值

编辑:查看评论。“据我所知”似乎还不够。然而,史蒂夫·杰索普(Steve Jessop)有一个不同的例子,使整体观点有效


这与您的增量问题完全无关,但与您的问题标题相关,因此我认为应该提及。

我非常确定第一个剪接的输出是未定义的,第一个片段有未定义的行为。隐藏采访的可能重复问题是:
你能检测到这是未定义的行为吗?
@Als:谢谢你在我的答案中提供更好的链接,但它不是直接重复的。这个问题的主要主题是模拟类wrt这样的整数。增量。如果两个运算符都重载,则行为不再是未定义的-每个运算符都成为一个函数调用,这将引入一个序列点。正如你所说,结果仍然是未知的。@Mike:不要只是删除你的评论,然后再做一个新的评论P但是,是的,你说得对,运算符成为函数调用的乐趣。你不妨加上引用标准C++03第5节:表达式,第4段:除非另有说明[例如,&&和| |]的特殊规则,单个运算符的操作数和单个表达式的子表达式的求值顺序,副作用发生的顺序是
Unspecified
@MikeSeymour,@Xeo:在重载的情况下,“+”操作数的唯一求值顺序是Unspecified;但它不是UB,i=i+++i++的最终结果可能通过正确实现+和++来指定(如果实现尊重numeric+运算的幺半群属性,并将++视为返回先前值的+e)。。。对不起,“+”的交换性是必需的,而且几乎已经足够了:),但我认为如果您想模拟整数类型,就不需要重新实现这些运算符。运算符
&&
| |
可以自动调用类“
运算符bool()
,在这种情况下,它们的短路行为是守恒的。尽管这是不可能的,但这是事实。一个更有力的原因是,将类A的实例隐式转换为(例如)
long
,“使用”了隐式转换中允许的1个用户定义的转换,而将
int
转换为
long
则不会。所以如果你有另一个
-- post-increment: 3
-- post-increment: 4
-- addition: 3+2
-- assign: 5
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
int i = 2;
i = i++ + i++;
int i = 2;
i = i++ + i++;