我实现了一个类来处理一些外部函数(例如另一个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
中更改了分配对象的值。我的问题是:这是个坏主意吗?有谁能更好地解决我的问题?
答案 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 &&)
确保没有两个对象拥有相同的手柄。确保删除了复制和赋值,并移动了赋值和移动构造函数,使右侧的句柄无效。
您的对象应该拥有手柄。手柄应该只有一个所有者。