fir*_*ush 3 c++ stdmap c++11 std-function
有没有办法从std :: map指向构造函数?我想用我想要使用的代码执行以下操作,#if 0但我似乎无法使其工作:
#include <map>
#include <functional>
using namespace std;
class Base { };
class A : public Base { };
class B : public Base { };
enum class Type { A, B, };
#if 0
using type_map_t = std::map<Type, std::function<Base*()>>;
type_map_t type_map = {
{Type::A, &A::A},
{Type::B, &B::B},
};
#endif
Base*
getBase(Type t)
{
#if 0
auto constructor = type_map[t];
return constructor();
#else
switch(t)
{
case Type::A:
return new A();
case Type::B:
return new B();
}
#endif
}
int
main(int argc, char *argv[])
{
Base *base = getBase(Type::A);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我没有在getBase中使用switch语句,而是让映射指示为每种类型调用的构造函数.
想到如何执行此操作会想到std :: function,但似乎无法在C++中获取构造函数的地址.有没有一种优雅的方式来完成我想要做的事情?
您不能根据C++标准(C++ 98/03的第12.1.12节和C++ 11的第12.1.10节)获取构造函数的地址:
构造函数 - 不应采用构造函数的地址.
对于这个问题,典型的解决方案是创建创建对象的特定工厂/方法.
有几点:
构造函数是一段获取原始内存并将其转换为对象的代码。这意味着您必须拥有适量的可用内存。
没有任何机制可以让您像普通函数一样访问构造函数,因为:构造函数的this指针在构造开始时就已经知道,并且无法传递指针。解决这些限制的方法是使用operator new. 通常operator new会分配对象所需的内存,如果分配成功则应用构造函数代码。(或者,有一个“放置new”,允许程序员为对象提供指向“足够内存”的指针。它用于“放置”构造,您事先分配了合适的缓冲区。通常,这些东西位于容器中仅图书馆。)
因此,您在地图中放入的内容将必须new在函数中使用。通常new就可以了,因为您没有任何机制来传递原始内存。
使用 lambda,您的映射可能如下所示:
type_map_t type_map = {
{Type::A, []() -> Base* { return new A; } },
{Type::B, []() -> Base* { return new B; } },
};
Run Code Online (Sandbox Code Playgroud)
该构造[]() -> Base*表示以下代码块被视为不带任何参数(-list 中不包含任何内容())、周围范围中不包含任何内容([]-list 中不包含任何内容)的函数体,并返回一个Base*. 它可用作std::function<Base*()>持有者对象的初始化值。
您也可以直接调用您的地图条目:
Base* base = type_map[Type::A]();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
904 次 |
| 最近记录: |