【问题标题】:C++ call constructor from class pointer?C++ 从类指针调用构造函数?
【发布时间】:2018-04-16 08:20:50
【问题描述】:

我希望能够从字符串初始化一个类(我给出“MyClass”,它会创建一个对象 MyClass)。

我知道这样做是不可能的,所以我创建了一个类,它有一个映射,其中一个字符串作为键,一个指向函数(创建对象)的指针作为值。

动态创建对象对这个和我的地图来说不是问题。

template<typename T> JsonSerializable* createInstance() { return new T; }

我的问题是我想将类动态添加到我的地图中。那可能吗 ? 我该怎么办:

void MyFactory::addNewClass(std::string& name, class c)
{
    map[name]=&createInstance<c>();
}

我可以将指针或其他东西传递给类本身(而不是对象)吗?并使用它来动态创建所有内容。

如果不可能,我将不得不对其进行硬编码。

【问题讨论】:

  • 你可能想要map[name]=&amp;createInstance&lt;c&gt;;。你想把函数放在那里,而不是对象。我想。如果你显示map的类型会更清楚。
  • 您可能对std::function感兴趣。
  • @nwp 我已经更正了,这是我过去的错误副本。我的问题不是调用构造函数,我的问题是将类作为类而不是对象传递。
  • 你像 template &lt;class T&gt; void MyFactory::addNewClass(std::string&amp; name){map[name]=&amp;createInstance&lt;T&gt;;} 一样传递它以像 myFactory.addNewClass&lt;Foo&gt;("Foo"); 一样被调用。
  • @mco 在我看来每个createInstance&lt;c&gt; 都有JsonSerializable *(*)(); 类型。

标签: c++ types generic-programming


【解决方案1】:

好的。因此,如果您使用的是 C++11,那么 lambda 可以帮助您获得所需的通用行为。

首先,我们需要一个SuperBase,所有的类都应该像这样派生出来

class SuperBase {};
class A : public SuperBase {};

class B: public SuperBase {};

然后创建一个以std::string 为键和std::function 为值的映射。

map<string,std::function<SuperBase*()>> myMap;

函数返回类型为SuperBaseaddNewClass函数可以定义为

template <typename type>
void addNewClass(std::string name) {
    myMap[name] = []() { return new type();};
  }

所以你可以从主函数中调用函数

addNewClass<A>("A");
addNewClass<B>("B");

然后在迭代时你可以调用函数来获取你想要的指针

 for( auto mapPair : myMap) {
        cout<<mapPair.first<<endl;
        SuperBase * sBase = mapPair.second();
    }

请记住,您需要 SuperBase 中的 virtual 函数具有多态行为,然后一切正常

希望对你有帮助

【讨论】:

  • 需要指定lambda的返回类型,否则会被推断为type。这样做:[]() -&gt; SuperBase* { return new type();};
  • 正确。这是一个很好的做法,但不是强制性的,因为它设法为所有类型推断出自己..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多