gpt4 book ai didi

c++ - 工厂、unique_ptr 和 static_cast

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

考虑具有基对象、派生接口(interface)和最终对象的多态类:

// base object

struct object
{
virtual ~object() = default;
};

// interfaces derived from base object

struct interface1 : object
{
virtual void print_hello() const = 0;

template<typename T>
static void on_destruction(object* /*ptr*/)
{
std::cout << "interface1::on_destruction" << std::endl;
}
};

// final object

struct derived1 : interface1
{
virtual void print_hello() const override
{
std::cout << "hello" << std::endl;
}

static std::string get_type_name()
{
return "derived1";
}
};

在实际用例中,最终对象是通过插件系统定义的,但这不是重点。请注意,我希望能够在销毁对象时调用 on_destruction(请参阅下面的 register_object)。我想按如下方式使用这些类:

int main()
{
// register derived1 as an instantiable object,
// may be called in a plugin

register_object<derived1>();

// create an instance using the factory system

auto instance = create_unique<interface1>("derived1");
instance->print_hello();

return 0;
}

使用 std::unique_ptr 来管理对象,我最终得到了以下 register_object 代码:

template<typename T>
using unique = std::unique_ptr<
T,
std::function<void(object*)> // object deleter
>;

namespace
{
std::map< std::string, std::function<unique<object>(void)> > factory_map;
}

template<typename T>
void register_object()
{
factory_map.emplace(
T::get_type_name(),
[]()
{
unique<T> instance{
new T,
[](object* ptr)
{
T::on_destruction<T>(ptr);

delete ptr;
}
};

return static_move_cast<object>(
std::move(instance)
);
}
);
}

创建* 函数:

unique<object> create_unique_object(const std::string& type_name)
{
auto f = factory_map.at(type_name);
return f();
}

template<typename T>
unique<T> create_unique(const std::string& type_name)
{
return static_move_cast<T>(
create_unique_object(type_name)
);
}

您注意到在 register_objectcreate_unique 中调用了 static_move_cast,声明为:

template<typename U, typename T, typename D>
std::unique_ptr<U, D>
static_move_cast
(
std::unique_ptr<T, D>&& to_move_cast
)
{
auto deleter = to_move_cast.get_deleter();

return std::unique_ptr<U, D>{
static_cast<U*>(
to_move_cast.release()
),
deleter
};
}

static_move_cast 背后的目标是允许在 std::unique_ptr 上进行 static_cast,同时在转换期间移动删除器。代码正在运行,但我想破解 std::unique_ptr。有没有办法重构代码来避免我的 static_move_cast

最佳答案

static_move_castregister_object 内是不必要的, 因为你可以只使用 converting constructor of unique_ptr template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ) :

        unique<T> instance{
new T,
// ...
};

return instance;

或者,更简单,构造并返回一个 unique<object>直接,因为T*可转换为 object* :

        return unique<object>{
new T,
// ...
};

但是对于 create_unique使用static_move_cast是不可避免的,因为 unique_ptr 的转换构造函数不适用于沮丧。

请注意 shared_ptr static_pointer_cast , 它执行向下转换,但是 unique_ptr 没有对应的工具,大概是因为认为自己执行转换被认为是直接和正确的。

关于c++ - 工厂、unique_ptr 和 static_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39331226/

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