如何禁止从其他类型向临时对象赋值和隐式强制转换

How to disallow assigning to a temporary object and implicit casting from other type?

本文关键字:赋值 临时对象 转换 类型 何禁止 禁止 其他      更新时间:2023-10-16

我为普通对象和临时对象重载了两次=运算符。不幸的是,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;

我试着添加&amp;=在我的运算符声明末尾删除,但编译器引发了编译错误。我试图在类范围之外实现这个运算符,但没有效果。

第一个问题是您是否真的想维护代码来抑制这些情况。通常,对于一个类类型,允许将赋值给一个临时(右值),就像它调用任何其他成员函数一样。在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;
};

虽然说实话,我只是禁止隐式转换,剩下的留给类的用户。