具有临时对象的 Fundamenta 数据类型赋值运算符
Fundamenta data type assignment operator with temporary objects
你好,所以我试图了解引擎盖下发生了什么。
int* puter;
puter = std::make_unique<int>(50).get();
if(puter) { std::cout << *puter << std::endl; }
起初,我认为推杆应该是一个悬空的 ptr,因为来自make_unique的临时unique_ptr会随着分配的资源一起被摧毁。但事实并非如此。 过了一会儿,我明白了,如果将unique_ptr资源分配给推杆,可能不会发生这种情况。 但真正的问题是。我什么时候应该假设事情会从临时中转移?有规则吗?在这种情况下,我应该只使用释放方法来保证吗?
正如其他人所提到的,这实际上会触发未定义的行为。
你最初的想法正是发生的事情
起初我认为推杆应该是一个悬空的 ptr,因为来自make_unique的临时unique_ptr会随着分配的资源一起被摧毁
因此
if(puter) { std::cout << *puter << std::endl; }
导致未定义的行为 - 你不知道那里有什么,不同的编译器和机器可以有不同的结果(例如,可以是 50,可以是 0,可以是 nullptr,或者一些垃圾值......
但真正的问题是。我什么时候应该假设事情会从临时中转移?有规则吗?在这种情况下,我应该只使用释放方法来保证吗?
这取决于类型/类是否支持移动语义(即定义了移动构造函数/移动赋值运算符)。如果没有,则与复制相同。
在这种情况下,int* 是基元类型,基元类型没有移动构造函数/赋值,因此临时赋值不会是移动赋值。
另一方面,如果你将一个临时的 std::vector 分配给另一个 std::vector,移动赋值将被调用,因为 std::vector 类有一个定义良好的移动赋值运算符(和一个移动构造函数)。
std::vector<int> v;
v = std::vector<int>{1,2,3}; //RHS is a temporary object, so it will call the vector's move assignment operator
相关文章:
- 标准库类型的赋值运算符的引用限定符
- 如果类在 C++ 中具有常量或引用类型的非静态数据成员,为什么编译器不提供默认赋值运算符?
- C++不同类型的默认赋值运算符
- 为什么类的赋值运算符的返回类型通常是非常量(而不是常量)引用?
- 具有临时对象的 Fundamenta 数据类型赋值运算符
- 引用模板类型的赋值运算符需要非常量重载
- 是否应该在复制构造函数或赋值运算符中复制静态数据成员
- 是否有必要重载具有另一个类 B 的数据成员的类 A 的赋值运算符和复制构造函数?
- 如何实现赋值运算符,使多个实例共享公共数据
- 带有非类型参数的C++模板类:如何重载赋值运算符
- C++通用数据结构 - 数据字段赋值运算符与复制 C'Tor
- 当我们给char数据类型赋值为负值时,它为什么表现得像int数据类型
- 重载全常量类型的复制赋值运算符的正确方法是什么?
- 重载非类型模板结构的成员结构的复制赋值运算符
- 表达式模板的核心功能:赋值运算符子模板类型
- 如何重载赋值运算符以允许我的类等于基元类型,例如'int'
- 如果类具有引用数据成员,为什么编译器不合成默认赋值运算符
- 返回赋值运算符的类型
- 重载赋值运算符:不同的数据类型-不可能
- 从"int"到非标量类型赋值运算符的转换 - 对象到 int