分配运算符更改分配对象的值

时间:2019-03-25 10:22:14

标签: c++ destructor assign

我实现了一个类来处理一些外部函数(例如另一个DLL)。这个函数给了我一个可以用作句柄的整数。这是我的代码的重要部分:

negate => true

在我的主要功能中,我有一个myClass对象。在某些时候,我正在使用赋值运算符来更改对象的值:

MyClass
{
public:
    MyClass() { 
        handle = getHandlefromExternalFunction();
    }
    ~MyClass {
        if(handle>0)
            freeHandleFromExternalFunction(handle);
    }
    MyClass& operator=(MyClass& other) {
        freeHandleFromExternalFunction(handle);
        handle = other.handle
        other.handle = 0; //Is this a bad idea?
    }
private:
    int handle;
}

分配后,MyClass object; //some code object = MyClass(); 创建的对象由于超出范围而被立即销毁。但是我不希望在该MyClass()上调用freeHandleFromExternalFunction(),因为我正在分配的对象中使用它。因此,我在分配运算符handle中更改了分配对象的值。我的问题是:这是个坏主意吗?有谁能更好地解决我的问题?

2 个答案:

答案 0 :(得分:6)

是的,这是一个坏主意。通常,您通常不希望分配的右侧被修改。

如果要移动所有权,则将“ move”赋值运算符与std::move一起使用:

MyClass& operator=(MyClass&& other) { ... }

// ...

MyClass a = ...;
MyClass b;

b = std::move(a);

如果您仅 想要这样的移动(其中只能是所包含资源的一个所有者),那么我还建议您将复制构造函数和复制赋值运算符标记为已删除:< / p>

MyClass& operator=(MyClass const&) = delete;
MyClass(MyClass const&) = delete;

the rule of five之后,请不要忘记移动构造函数和析构函数:

~MyClass() { ... }
MyClass(MyClass&& other) { ... }

答案 1 :(得分:1)

class MyClass {
public:
   //....
   MyClass& operator=(MyClass& other)

分配中的非常量other是一个坏主意,并且很容易使程序员感到惊讶。大多数程序员不希望赋值的右侧发生突变。

这也不会编译:

MyClass obj;
obj = MyClass(); // error 

要对此进行编译,必须使用移动语义,这可能就是一开始的意思: 类MyClass2 {     上市:        // ....        MyClass2&operator =(const MyClass2&other)=删除;        MyClass2&operator =(MyClass2 && other)

&&表示other可以在此过程中清空:

 MyClass2 obj, obj2, obj3;
 obj = MyClass2(); // ok. Will be moved
 obj2 =std::move(obj); // ok
 obj3 = obj2; // error, not an rvalue rference (not MyClass2 &&)

确保没有两个对象拥有相同的手柄。确保删除了复制和赋值,并移动了赋值和移动构造函数,使右侧的句柄无效。

您的对象应该拥有手柄。手柄应该只有一个所有者。