gpt4 book ai didi

c++ - 具有 unique_ptr 的用户友好型 API

转载 作者:可可西里 更新时间:2023-11-01 18:29:28 24 4
gpt4 key购买 nike

我正在为 OpenGL 实现一个简单的 GUI,主要是作为我自己的练习。这个想法是有一个 Gui 类,其中每个实例都可以分配给不同的渲染目标(例如后台缓冲区或纹理)。 GUI 元素(小部件)恰好分配给 Gui 类的一个实例。我想在 GUI 中存储元素是 unique_ptr 的典型用例.这是我想出的:

class Element {
public:
Element();
virtual ~Element();

static std::unique_ptr<Element> create_unique();
};

class Gui {
public:
typedef std::unique_ptr<Element> element_ptr;
Gui();
void addElement( element_ptr element );
void addElementRaw( Element* element );

private:
std::list<element_ptr> elements;
};

int main(void) {
Gui gui;

gui.addElementRaw( new Element() ); // 1

gui.addElement( Element::create_unique() ); // 2

gui.addElement( std::unique_ptr<Element>(new Element()) ); // 3

auto el = Element::create_unique();
gui.addElement( std::move(el) ); // 4
}

我不希望 GUI 的潜在用户担心移动指针。但是,我想通过 API 明确表示 GUI 类拥有元素的所有权。

  1. 传递原始指针:使用简单,但 API 并未明确表示所有权已传递。
  2. 工厂函数:使用简单,但需要为每个从Element派生的类重新实现该函数。
  3. 手动创建 unique_ptr:对用户来说很麻烦
  4. 移动语义:看起来也很麻烦。

我对我的解决方案不满意。我想要的是 (1) 的简单性,同时从 API 中清楚地表明 gui 现在拥有该元素。

最佳答案

只为新元素提供参数怎么样?

template< typename... T >
void addElement( T&&... t )
{
elements.emplace_back( std::unique_ptr< Element >( new Element( std::forward< T >( t )... ) ) );
}

对于 C++14,您还可以使用 std::make_unique:

template< typename... T >
void addElement( T&&... t )
{
elements.emplace_back( std::make_unique< Element >( std::forward< T >( t )... ) );
}

如果你想创建从 Element 派生的元素,你也可以这样做(C++14 版本):

template< typename C, typename... T >
void emplace_back( T&&... t )
{
elements.emplace_back( std::make_unique< C >( std::forward< T >( t )... ) );
}

它可以像这样使用:

gui.emplace_back< Element >();

// insert a class derived from Element (hope you have a virtual dtor!)
gui.emplace_back< DerivedFromElement >();

// calls Element::Element( int, const char* ) or similar...
gui.emplace_back< Element >( 42, "Hallo" );

关于c++ - 具有 unique_ptr 的用户友好型 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20924591/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com