C++ C++;方法调用不带if/elseif/elseif/elseif/else的特定函数

C++ C++;方法调用不带if/elseif/elseif/elseif/else的特定函数,c++,class,C++,Class,我想创建一个函数,该函数接受的字符串可能是: “三角形”、“正方形”或“矩形” 根据这个参数,我想返回一个类窗体上的指针 我有一个母亲班“形”,她继承了班矩形、班方形和班矩形 但我不想这样做: if (name == "rectangle") return (new Rectangle()); else if (name == "square") return (new Square()); ... etc 我考虑过函数上的指针,但我想要

我想创建一个函数,该函数接受的字符串可能是: “三角形”、“正方形”或“矩形”

根据这个参数,我想返回一个类窗体上的指针

我有一个母亲班“形”,她继承了班矩形、班方形和班矩形 但我不想这样做:

if (name == "rectangle")
    return (new Rectangle());
else if (name == "square")
    return (new Square());
... etc
我考虑过函数上的指针,但我想要最简单的方法和干净的代码,你推荐什么


谢谢你

是的,您可以使用函数指针或lambda。您可以使用字符串到函子的映射:

std::map<std::string, std::function<ShapeBase*()>> actions = {
    { "rectangle", []{return new Rectangle;} },
    { "square", []{return new Square;} }
};

return actions[name]();

switch
语句将被优化,以便对整数散列值进行二进制搜索或类似的搜索。如果出现哈希冲突,还将出现编译时错误。

您可以使用
std::unordered\u map

using FormPtr = std::unique_ptr<Form>;
using Creators = std::unordered_map<std::string,std::function<FormPtr()>>;

FormPtr create( const std::string &name )
{
    const static Creators creators {
        { "triangle", [] { return std::make_unique<Triangle>(); } },
        { "square", [] { return std::make_unique<Square>(); } },
        { "rectangle", [] { return std::make_unique<Rectangle>(); } }
    };
    auto f = creators.find( name );
    if( f == creators.end() ) {
        // error handling here
    }
    return f->second();
}
使用FormPtr=std::unique\u ptr;
使用Creators=std::无序映射;
FormPtr创建(const std::string和name)
{
常量静态创建者{
{“三角形”],[{return std::make_unique();}},
{“square”[]返回std::make_unique();},
{“矩形”,[]返回std::make_unique();}
};
自动f=创建者。查找(名称);
if(f==creators.end()){
//这里的错误处理
}
返回f->second();
}

如果您需要在外部添加创建者,您可以将他们放入一个类中,允许他们更新地图并动态注册更多的创建者。

为什么您不想使用有效的代码来完成这项工作?我想要一种干净的方法,想象一下,如果我有500个表单:)为什么您认为这不干净?这是我能想到的最干净的。不管有多少类,假设您有1000个类,那么您仍然需要以某种方式将字符串映射到构造函数调用。而你的代码确实如此that@largest_prime_is_463035818首先,对于1000个字符串,级联
if
可能效率很低lookups@Slava这是关于效率而不是清洁度的问题,尽管这是有道理的。我会闭嘴:)你最好使用
std::unordered\u map
进行散列,你假设散列总是唯一的,但这不是真的,所以你的代码可能有误报。散列没有映射。这是一个
switch
语句,在编译时大小写必须是唯一的。是的,但生成的哈希不必是唯一的,而且未注册的字符串可能会创建不相关的类,这是一个非常讨厌的包,不容易创建catch@FrançoisAndrieux问题是错误的,例如单词“rectuangle”可以在运行时使用,如果运气不好,将生成与“圈”相同的哈希值,那么好运会发现这个问题。或者可能是
std::unordered_map
creaters做了一个愚蠢的工作来检查散列冲突?@Slava这是一个很好的心态。“纯粹的运气”有点夸张。:-)我想可以通过检查每个
案例中的相等性来扩展散列开关,以实现基于散列的容器的功能<代码>大小写哈希(“square”):如果(name==“square”)…
可能打包在宏中。
using FormPtr = std::unique_ptr<Form>;
using Creators = std::unordered_map<std::string,std::function<FormPtr()>>;

FormPtr create( const std::string &name )
{
    const static Creators creators {
        { "triangle", [] { return std::make_unique<Triangle>(); } },
        { "square", [] { return std::make_unique<Square>(); } },
        { "rectangle", [] { return std::make_unique<Rectangle>(); } }
    };
    auto f = creators.find( name );
    if( f == creators.end() ) {
        // error handling here
    }
    return f->second();
}