如何禁止从其他类型向临时对象赋值和隐式强制转换
How to disallow assigning to a temporary object and implicit casting from other type?
我为普通对象和临时对象重载了两次=运算符。不幸的是,g++(Debian 4.7.2-5)4.7.2允许过多的临时对象。例如,他不应该允许为临时对象赋值。他还允许将其他类型的变量分配给对象。
#include <cstdlib>
#include <utility>
#include <iostream>
using namespace std;
class Simple {
int number;
public:
int getNumber() const {
return number;
}
Simple(const Simple& that) : number(that.number) {}
Simple(Simple&& that) : number(move(that.getNumber())) {}
Simple(int a) {number = a;}
Simple& operator=(const Simple &base) {
if (&base != this) {
this->number = std::move(base.getNumber());
}
return *this;
}
Simple& operator=(Simple&& base) {
if (&base != this) {
this->number = std::move(base.getNumber());
}
return *this;
}
};
Simple reverse(const Simple& base) {
Simple result(base.getNumber());
return result;
}
int main(int argc, char** argv) {
Simple one(4);
Simple two(5);
one = two.getNumber();//This should be compile error.
reverse(two) = one;This should be compile error.
return 0;
}
如何更改此代码以禁止分配给临时对象以及其他类型的隐式铸造?
附加信息:如何使此指令可实施:
Simple& operator=(Simple const &) && = delete;
我试着添加&;=在我的运算符声明末尾删除,但编译器引发了编译错误。我试图在类范围之外实现这个运算符,但没有效果。
第一个问题是您是否真的想维护代码来抑制这些情况。通常,对于一个类类型,允许将赋值给一个临时(右值),就像它调用任何其他成员函数一样。在C++11中及以后的右值引用中,您可以在重载解析期间区分右值和左值,这可以用来阻止右值的赋值。要阻止int
的赋值,您可以禁止所有隐式转换(我建议不要进行隐式转换),也可以阻止特定的赋值运算符:
class Simple {
// ...
// Disallow implicit conversions from int
explicit Simple(int);
// Inhibit assignment to rvalues
Simple& operator=(Simple const &) && = delete;
// Alternatively, require that it is called on an lvalue
Simple& operator=(Simple const &s) &;
Simple& operator=(Simple &&) &;
// ... or block assigment from 'int'
Simple& operator=(int) = delete;
};
虽然说实话,我只是禁止隐式转换,剩下的留给类的用户。
相关文章:
- 复制包含C++所有元素的对象!(构造函数和赋值,最佳实践?
- 临时C++对象是否为左值?
- 如何动态地为对象中的数据赋值?
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 为什么引用类型在使用临时对象访问时是左值
- 为什么可以使用已删除的移动构造函数和赋值运算符移动对象?
- 构造函数对象赋值是否泄漏内存
- 为什么对象可以"moved"甚至缺少移动构造函数和移动赋值运算符?
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 是否可以在C++(17)中捕获某些对象属性的破坏性赋值事件
- 具有临时对象的 Fundamenta 数据类型赋值运算符
- 如何重载 const 对象的 [],以便值赋值不会导致编译错误
- 重载运算符 -- 无法在赋值中将对象转换为基类型
- C++ 矢量从构造函数赋值对象,无需临时
- 赋值类对象的值
- 简单的引用变量赋值导致对象的全局指针出现segfault
- 如何禁止从其他类型向临时对象赋值和隐式强制转换
- 给引用形参赋值使对象无效