unique_ptr 让人头疼的设计
design headache with unique_ptr
假设我们有 class Foo
:
class Foo {
public:
...
};
Foo
有一个实例方法,可以将 Foo
实例转换为另一个 Foo
实例,或者 returns 相同的 Foo
实例:
<some appropriate pointer type to Foo> Foo::tryToTransform() {
if (canBeTransformed()) {
<delete this Foo instance>;
return <new instance of Foo>;
}
else {
return <this instance of Foo>;
}
}
客户代码:
<some appropriate pointer type to Foo> foo = ...;
...
foo = foo->tryToTransform();
使用裸指针很容易做到这一点:
Foo* Foo::tryToTransform() {
if (canBeTransformed()) {
delete this;
return new Foo(...);
}
else {
return this;
}
}
Foo* foo = ...;
...
foo = foo->tryToTransform();
但是如果客户端代码使用 unique_ptr
而不是裸指针呢?也就是说,理想情况下我希望客户端代码如下所示:
unique_ptr<Foo> foo = ...;
...
foo = foo->tryToTransform();
如何定义 Foo::tryToTransform()
以启用此类(或类似)客户端代码?
因为您的 tryToTransform
函数是一个 成员函数 ,调用者保留 unique_ptr
的所有权。因此,不可能(没有肮脏的技巧)从成员函数内部删除调用者的 unique_ptr
。
因此,您需要一个获取unique_ptr
:
所有权的静态函数
class Foo {
static unique_ptr<Foo> tryToTransform(unique_ptr<Foo> ptr) {
if(...) {
return unique_ptr<Foo>(new Foo()); // old ptr is destroyed
} else {
return ptr;
}
};
调用为
unique_ptr<Foo> foo = ...;
...
foo = Foo::tryToTransform(move(foo));
这通过让 tryToTransform
获得 unique_ptr
的所有权来实现。然后它就可以随心所欲地销毁指针。
假设我们有 class Foo
:
class Foo {
public:
...
};
Foo
有一个实例方法,可以将 Foo
实例转换为另一个 Foo
实例,或者 returns 相同的 Foo
实例:
<some appropriate pointer type to Foo> Foo::tryToTransform() {
if (canBeTransformed()) {
<delete this Foo instance>;
return <new instance of Foo>;
}
else {
return <this instance of Foo>;
}
}
客户代码:
<some appropriate pointer type to Foo> foo = ...;
...
foo = foo->tryToTransform();
使用裸指针很容易做到这一点:
Foo* Foo::tryToTransform() {
if (canBeTransformed()) {
delete this;
return new Foo(...);
}
else {
return this;
}
}
Foo* foo = ...;
...
foo = foo->tryToTransform();
但是如果客户端代码使用 unique_ptr
而不是裸指针呢?也就是说,理想情况下我希望客户端代码如下所示:
unique_ptr<Foo> foo = ...;
...
foo = foo->tryToTransform();
如何定义 Foo::tryToTransform()
以启用此类(或类似)客户端代码?
因为您的 tryToTransform
函数是一个 成员函数 ,调用者保留 unique_ptr
的所有权。因此,不可能(没有肮脏的技巧)从成员函数内部删除调用者的 unique_ptr
。
因此,您需要一个获取unique_ptr
:
class Foo {
static unique_ptr<Foo> tryToTransform(unique_ptr<Foo> ptr) {
if(...) {
return unique_ptr<Foo>(new Foo()); // old ptr is destroyed
} else {
return ptr;
}
};
调用为
unique_ptr<Foo> foo = ...;
...
foo = Foo::tryToTransform(move(foo));
这通过让 tryToTransform
获得 unique_ptr
的所有权来实现。然后它就可以随心所欲地销毁指针。