Bil*_*eal 6 c++ smart-pointers auto-ptr copy-constructor
回到我疯狂的AutoArray东西 ......(引用那里的重要部分:
class AutoArray
{
void * buffer;
public:
//Creates a new empty AutoArray
AutoArray();
//std::auto_ptr copy semantics
AutoArray(AutoArray&); //Note it can't be const because the "other" reference
//is null'd on copy...
AutoArray& operator=(AutoArray);
~AutoArray();
//Nothrow swap
// Note: At the moment this method is not thread safe.
void Swap(AutoArray&);
};
Run Code Online (Sandbox Code Playgroud)
)
无论如何,试图实现复制构造函数.有一段客户端代码(尚未提交到bitbucket,因为它不会构建),如下所示:
AutoArray NtQuerySystemInformation(...) { ... };
AutoArray systemInfoBuffer = NtQuerySystemInformation(...);
Run Code Online (Sandbox Code Playgroud)
这失败是因为复制构造函数将非const引用作为参数....但是我没有看到如何修改复制构造函数以获取const引用,因为AutoArray赋值中使用的源被修改(因此不会不会const.你当然不能修改使用pass by value的东西,因为它是复制构造函数,并且它是一个无限循环!
如果我使用auto_ptr,这将是有效的:
std::auto_ptr NtQuerySystemInformation(...) { ... };
std::auto_ptr systemInfoBuffer = NtQuerySystemInformation(...);
Run Code Online (Sandbox Code Playgroud)
那么,具有auto_ptr复制语义的类是否可以实现呢?
Jam*_*lis 14
auto_ptr 使用肮脏的技巧.
我将使用一个名为dumbed-down的类auto_int来演示复制构造功能,而不会带来模板或继承引入的任何复杂性.我认为代码大多是正确的,但它没有经过测试.我们的基本auto_int外观如下:
class auto_int
{
public:
auto_int(int* p = 0) : p_(p) { }
~auto_int() { delete p_; }
// copy constructor taking a non-const reference:
auto_int(auto_int& other)
: p_(other.release()) { }
int* release()
{
int* temp = p_;
p_ = 0;
return temp;
}
private:
int* p_;
};
Run Code Online (Sandbox Code Playgroud)
有了这个基础auto_int,我们就无法复制临时对象了.我们的目标是能够写出如下内容:
auto_int p(auto_int(new int()));
Run Code Online (Sandbox Code Playgroud)
我们能做的是使用帮助类.因为auto_ptr,这被称为auto_ptr_ref.我们称之为我们的auto_int_ref:
class auto_int;
class auto_int_ref
{
public:
auto_int_ref(auto_int* p) : p_(p) { }
auto_int& ref() { return *p_; }
private:
auto_int* p_;
};
Run Code Online (Sandbox Code Playgroud)
基本上,这个类的一个实例只存储一个指针,auto_int并允许我们将它用作一个"引用" auto_int.
然后在我们auto_int班上我们需要两个额外的功能.我们需要另一个构造函数,它auto_int_ref需要一个转换运算符,允许auto_int隐式转换为auto_int_ref:
auto_int(auto_int_ref other)
: p_(other.ref().release()) { }
operator auto_int_ref() { return this; }
Run Code Online (Sandbox Code Playgroud)
这将允许我们"复制"一个临时的,同时仍然让复制构造函数采用非const引用.如果我们再看一下我们的示例代码:
auto_int p(auto_int(new int()));
Run Code Online (Sandbox Code Playgroud)
会发生什么是我们构造一个新的临时文件auto_int并传递new int()给构造函数int*.然后将此临时转换为auto_int_ref指向它的临时值,使用operator auto_int_ref()和用于初始化的auto_int构造auto_int_ref函数p.