在没有模板的情况下使用任意所属指针
Using arbitrary owning pointer without templating
我想将对象的(共享)所有权传递给函数foo::bar
。问题是,我不在乎所有权是独占的还是共有的。我认为class foo
是一个接口,我不想关心所有权细节。我所关心的是,我可以确保传递的智能指针的生命周期超过foo::bar
的返回。
现在我可以写
class foo {
void bar( std::shared_ptr<blub> );
void bar( std::unique_ptr<blub> );
};
,但这是不优雅的时候,我们积累了几个智能指针的变体。为每个变体编写重载是相当麻烦的,特别是如果我想在代码中多次使用这种方案。
现在我也不希望foo
被模板化,因为明显的模板复杂性。
我能想到的最简单的方法就是一个智能指针包装器
template <typename T>
class owning_ptr {
// Sorts out the largest type so we can allocate enough space
typedef largest<std::shared_ptr<T>, std::unique_ptr<T>, myptr<T>>::type big_type;
typedef std::aligned_storage <sizeof(big_type), std::alignment_of<big_type>::value>::type buffer_type;
buffer_type _internal;
int _type;
};
有点低效。是否有更好的方法来构造包装器?
最后我真的很想要签名:
class foo {
void bar( owning_ptr<blub> );
};
注意:底部有一个有趣的编辑
如果你不想对所属指针类型进行参数化或重载,你可能最好采用shared_ptr<>
并强制转换unique_ptr<>
。我能想到的任何非模板解决方案都至少具有与shared_ptr
相同的开销,大多数需要多态调用,自由存储分配,或两者兼而有。
您可以通过采用某种类型的代理转换器来自动从shared_ptr
进行转换,这应该允许您在没有强制转换或显式转换(move()
除外)的情况下获取unique_ptr
r值或shared_ptr
,并提取可用的shared_ptr
以存储在您的实例中。下面是一个例子:
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
// Take an instance of gimme_owned_ptr<T> to save off a shared_ptr<T>
// from either a shared_ptr or unique_ptr.
template<typename T>
struct gimme_owned_ptr {
// Make the two constructors templates so we can accept
// any convertible owning pointer:
template<typename S>
gimme_owned_ptr( unique_ptr<S> p )
: p_( shared_ptr<S>( move(p) ) )
{ }
template<typename S>
gimme_owned_ptr( shared_ptr<S> p )
: p_( p )
{ }
shared_ptr<T> get() const {
return p_;
}
private:
shared_ptr<T> p_;
};
struct Foo {
void operator()() const { v_call(); }
virtual ~Foo() { }
private:
virtual void v_call() const = 0;
};
struct Bar {
Bar( gimme_owned_ptr<Foo const> const &gop )
: foo_( gop.get() )
{ }
void operator()() const { (*foo_)(); }
private:
shared_ptr<Foo const> foo_;
};
struct Baz : Foo {
private:
virtual void v_call() const { cout << "Baz()()n"; }
};
int main() {
unique_ptr<Baz> upf( new Baz() );
shared_ptr<Baz> spf( new Baz() );
Bar upb( move( upf ) );
Bar spb( spf );
upb();
spb();
}
是的,此解决方案确实使用模板,但仅用于gimme_owned_ptr
实用程序类模板,并且仅用于重用和转换。您自己的类(在本例中是Bar
)不需要是模板,也不需要重新实现gimme_owned_ptr
来与其他类型一起使用它。
======== EDIT ========
我刚刚检查过,从unique_ptr
到shared_ptr
的内置转换基本上完成了我上面写的gimme_owned_ptr
类的所有操作。如果类的类型为shared_ptr<T>
,则传递move(unique_ptr<S>)
将导致可操作的转换。因此,您真正需要做的就是使用shared_ptr
,用户唯一需要做的就是在unique_ptr
s上调用move()
(无论如何他们都应该这样做)。使用gimme_owned_ptr
的唯一原因是接受不同的指针组合或以不同的方式接受它们。(例如,您可以通过获取unique_ptr<S>&
并在内部调用move()
来使move()
变得不必要,但这可能是一个坏主意,因为它将默默地夺取所有权。)
- C++ - 声明指向返回任何类型并获取任意数量参数的函数的指针
- 类型别名允许分配任意指针,尽管 int* 是必需的
- 指针可以用于访问内存中的任何任意区域吗?
- C++:访问作为函数参数传递的双指针数组所指向的变量的值
- 将 C 代码移植到C++,将 void* 从 malloc 转换为所需指针的问题
- 删除 c++ 中指针数组的每个元素所指向的相应元素
- 带有自定义类的共享指针语法背后的任何原因,如下所示
- 允许通过指向方法的成员参数的指针来推断模板参数所指向的成员类型
- C++:指针元素的向量在销毁时是否会自动释放每个指针所指向的动态内存?
- 如何动态执行具有任意参数类型的函数指针
- 使用已删除的指针地址.据我所知,
- 定义具有任意范围的指针
- 如何将唯一指针传递给函数中所需的特定参数
- 使用通用函数指针C++传递方法所需的类型参数
- 在C++中,是否可以将任意指针作为输入参数
- (C 14)操作员&lt;&lt;超负荷无法正如智能指针向量所预期的那样工作
- 保留存储在STL容器中的指针所指向的值(unordered_map)
- 在没有模板的情况下使用任意所属指针
- 如何创建一个可以容纳任意类型指针的容器?
- 如何在c++11中存储任意方法指针