您能解释一下以下代码的输出吗?变量在赋值结束时更改其值。
#include <iostream>
#include <new>
using namespace std;
template<class CRTP>
class object_t {
public:
object_t<CRTP> &operator=(const object_t<CRTP> &a) {
((CRTP*)this)->~CRTP();
new ((CRTP*)this) CRTP(*(const CRTP*)&a);
cout << "Value in assignment: " << ((CRTP*)this)->n << endl;
return *this;
}
};
class darr_t : public object_t<darr_t> {
public:
int n;
darr_t(const darr_t &a) : n(a.n + 1) {
cout << "Value in constructor: " << n << endl;
}
darr_t(int pn) : n(pn) {}
};
int main() {
darr_t tmp(42);
darr_t tmp2(55);
tmp = tmp2;
cout << "Value in main: " << tmp.n << endl;
return 0;
}
输出:
Value in constructor: 56
Value in assignment: 56
Value in main: 55
预期输出:
Value in constructor: 56
Value in assignment: 56
Value in main: 56
编辑: 感谢@Cheersandhth.-Alf 和@Mr_Hic-up 的回答! 问题是默认的 darr_t::operator= 首先调用基类型的赋值,但之后它为 darr_t 对象的成员调用赋值(覆盖)!
最佳答案
您观察该行为是因为:
- 编译器为
darr_t
定义了隐式复制赋值运算符。 - 隐式复制赋值首先调用基类的复制赋值运算符,然后再执行成员变量的复制赋值。
以下是来自 http://en.cppreference.com/w/cpp/language/as_operator 的相关文档:
Implicitly-declared copy assignment operator
If no user-defined copy assignment operators are provided for a class type (
struct
,class
, orunion
), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the formT& T::operator=(const T&)
if all of the following is true:each direct base
B
ofT
has a copy assignment operator whose parameters areB
orconst B&
orconst volatile B&
each non-static data member
M
ofT
of class type or array of class type has a copy assignment operator whose parameters areM
orconst M&
orconst volatile M&
Otherwise the implicitly-declared copy assignment operator is declared as
T& T::operator=(T&)
. (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)
关于C++ 赋值奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24330804/