C++ 分配奇怪的行为
C++ Assignment strange behaviour
你能解释一下以下代码的输出吗?变量在赋值结束时更改其值。
#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;
}
输出:
构造函数中的值:56
分配值:56
主值:55
预期产出:
构造函数中的值:56
分配值:56
主值:56
编辑:感谢@Cheersandhth.-阿尔夫和@Mr_Hic的回答!问题是默认的 darr_t::operator= 首先调用基类型的赋值,但之后它为对象的成员调用darr_t赋值(覆盖(!
您正在观察该行为,因为:
- 编译器为
darr_t
定义了一个隐式复制赋值运算符。
隐式复制赋值 - 首先调用基类的复制赋值运算符,然后再执行成员变量的复制赋值。
以下是 http://en.cppreference.com/w/cpp/language/as_operator 的相关文档:
隐式声明的复制赋值运算符
如果没有为类类型(
struct
、class
或union
(提供用户定义的复制赋值运算符,编译器将始终将一个声明为类的内联公共成员。如果满足以下所有条件,则此隐式声明的复制赋值运算符的格式为T& T::operator=(const T&)
:
T
的每个直接基B
都有一个复制赋值运算符,其参数为B
或const B&
或const volatile B&
类类型的
T
或类类型的数组的每个非静态数据成员M
都有一个复制赋值运算符,其参数为M
或const M&
或const volatile M&
否则,隐式声明的复制赋值运算符将声明为
T& T::operator=(T&)
。(请注意,由于这些规则,隐式声明的复制赋值运算符无法绑定到易失性左值参数(
new ((CRTP*)this) CRTP(*(const CRTP*)&a);
你试图拉动的指针魔术并没有按照你的期望去做。 在打印变量之前添加一些行以打印出对象的地址 yield(在我的机器上(:
Address in constructor: 0x7fff56264610
Value in constructor: 56
Address in assignment: 0x7fff56264610
Value in assignment: 56
Address in main: 0x7fff56264618
Value in main: 55
相关文章:
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源