C++ Can';t解释编译器&x27;行为
考虑以下简单代码:C++ Can';t解释编译器&x27;行为,c++,destructor,operator-keyword,C++,Destructor,Operator Keyword,考虑以下简单代码: class A { public: int value; A(int value) { this->value = value; } ~A() { printf("destroying %d\n", value); } A operator ++() { return A(value + 1); } }; int main() { A a(1); printf("before increment: %d\n", a.va
class A {
public:
int value;
A(int value) { this->value = value; }
~A() { printf("destroying %d\n", value); }
A operator ++() { return A(value + 1); }
};
int main() {
A a(1);
printf("before increment: %d\n", a.value);
a = ++a;
printf("after increment: %d\n", a.value);
return 0;
}
这将产生:
增量前:1销毁2
增量后:2
销毁2
为什么
a
1的值在被销毁之前会增加 很简单:
a = ++a;
首先,创建一个新的临时
对象,该对象保存值为2
(value+1=2
),该对象被移动/复制到a
,然后销毁(这是您看到的第一个销毁2
打印)。现在,编译器生成的move/copy构造函数只执行成员的memcopy,在本例中为value
<代码>值
分配给临时对象时为2
,因此a
的值也将为2
。因此,最后两个printf
打印出来的2
并不奇怪。在operator++方法中,您创建了一个临时对象,当您从函数返回该对象时,该对象将被销毁。也应该有另一个副本的建设和销毁,但省略了这一个
当您将日志添加到构造函数中时,您也会更好地看到正在发生的事情。我还允许自己将printf改为cout,以获得更多c++风格的编码
#include <iostream>
class A {
public:
int value;
A(int value) {
std::cout << "creating " << value << std::endl;
this->value = value;
}
~A() {
std::cout << "destroying " << value << std::endl;
}
A operator ++() { return A(value + 1); }
};
int main() {
A a(1);
std::cout << "before increment: " << a.value << std::endl;
a = ++a;
std::cout << "after increment: " << a.value << std::endl;
return 0;
}
您还可以阅读运算符重载的规范实现:
运算符++重载应如下所示:
struct X
{
X& operator++() // prefix version
{
// actual increment takes place here
return *this;
}
X operator++(int) // postfix version
{
X tmp(*this); // copy
operator++(); // pre-increment
return tmp; // return old value
}
};
基本上,为了清楚起见,您可以在这里将预增量运算符声明为常量
A operator ++() const { return A(value + 1); }
但预期的行为是:
A& operator ++() { ++value; return *this; }
你是指第一次还是第二次销毁?你的操作符+++()
应该在自身递增后返回一个引用(对自身),而不是创建一个新的临时a
。正如所写的,这段代码会让这个类的所有用户感到困惑。幸好您提到了实现这些运算符的合理方法。顺便说一句,如果OP以这种方式实现它,答案将是(如果内存服务器正确的话)未定义的行为,因为使用a=++a在一个表达式中修改相同的对象此表达式有三个部分:(1)“a”(2)++a”(3)“将(2)赋值给(1)”。(3) 保证在(1)和(2)之后发生,因此不,这里没有未定义的行为。是的,但如果++a
以将自身递增的方式实现,则表达式将导致未定义的行为。看见
A operator ++() const { return A(value + 1); }
A& operator ++() { ++value; return *this; }