那么,什么是四个半法则?哪些函数需要被实现,每个函数的主体应该是什么样子的?哪个函数是半个?与五个法则相比,这种方法有没有任何缺点或警告?
这里有一个类似于我的当前代码的参考实现。如果不正确,正确的实现应该是什么样子的?
#include <utility>
// "Handle management" functions. These would be defined in an external library.
typedef int* handle;
#define NO_HANDLE nullptr
extern handle get_handle(int value);
extern handle copy_handle(handle h);
extern void free_handle(handle h);
// This class automatically obtains a handle, and then frees it when the object
// leaves scope.
class AutoHandle {
public:
//We must have a default constructor so we can swap during copy construction.
//It need not be useful, but it should be swappable and deconstructable.
//It can be private, if it's not truly a valid state for the object.
AutoHandle() : resource(NO_HANDLE) {}
//Normal constructor, acquire resource
AutoHandle(int value) : resource(get_handle(value)) {}
//Copy constructor
AutoHandle(AutoHandle const& other) {
resource = copy_handle(other.resource);
}
//Move constructor
//Delegates to default constructor to put us in safe state.
AutoHandle(AutoHandle&& other) : AutoHandle() {
swap(other);
}
//Assignment
AutoHandle& operator=(AutoHandle other) {
swap(other);
return *this;
}
//Destructor
~AutoHandle() {
//Free the resource here.
//We must handle the default state that can appear from the copy ctor.
if (resource != NO_HANDLE)
free_handle(resource);
}
//Swap
void swap(AutoHandle& other) {
using std::swap;
//Swap the resource between instances here.
swap(resource, other.resource);
}
//Swap for ADL
friend void swap(AutoHandle& left, AutoHandle& right) {
left.swap(right);
}
private:
handle resource;
};
if (resource != nullptr) delete resource;
中的if
是不必要的。 - alainint*
然后想要深度复制?拥有一个“无用”的默认构造函数似乎不是最好的选择,特别是如果它只在奇怪的移动构造函数中使用 - 这将在std::swap
中构造另一个对象。这似乎不是移动构造函数应该具有的明显速度优化。此外,赋值运算符可能会调用std::swap
,当交换移动分配对象时,似乎会发生递归... - Bo Persson