在运行时将指针分配给多态类
Assign pointer to polymorphic class in runtime
类A包含一个指向抽象类B的指针(仅实现了头):
// A.h
#include "B.h"
class A {
public:
A();
virtual ~A();
pointBto(B* b_); // { this.b = b_; }
private:
B* b;
}
// B.h
class B {
public:
B();
virtual ~B();
virtual void b_method() = 0;
}
类C和D继承B.
// C.h
#include "B.h"
Class C : public B {
public:
C();
~C();
virtual b_method();
}
// D.h
#include "B.h"
Class D : public B {
public:
D();
~D();
virtual b_method();
}
应用程序读取一个字符串,并根据这个字符串创建一个C或D类的新对象,并将b指向创建的对象。
注意:我不想创建一个无尽的链
if (string_ == "C")
{
a_.pointBto(new C());
}
else if (string_ == "D")
{
a_.pointBto(new D());
}
else ...
只需创建一个std::map<std::string, std::function<B*(/*...*/)>>
:
static const std::map<std::string, std::function<B*(/*...*/)>> factory = {
{ "C", [](/*...*/){ return new C(/*...*/); },
{ "D", [](/*...*/){ return new D(/*...*/); },
};
a_.pointBto(factory[string_](/*arguments*/));
您要查找的内容通常被称为"虚拟构造函数"。我通常不喜欢这种结构,但它可以使用例如"克隆"习语来实现。类似以下内容:
struct Parent {
virtual Parent* clone(/*??? arg*/) = 0;
};
struct Child1 : Parent {
/*virtual */ Parent clone(/*??? arg*/) { return new Child1(/*arg*/); }
};
/* Child 2 */
Parent* make_parent(Choice arg) {
static std::map<Choice, Parent*> factory({{ch1, new Child1()}, {ch2, new Child2()}};
return factory.find(arg).second->clone(/**/);
}
最大的问题是clone
参数被简化为某种blob,这需要强制转换。
如果您想避免每次添加新的派生类时都会扩展If-else块(或其他类似的集中式机制),那么可以让派生类型自己注册。
检查这个线程的技巧如何做到:
有没有一种方法可以从包含对象类名的字符串中实例化对象?
(注意,对于给定的解决方案,字符串不需要与类名相同)。本质上,你仍然有一个从字符串到工厂函数的映射,即
map< std::string, std::function<B*()> >
不同之处在于,负责将回调添加到映射的代码是定义派生类的地方。
相关文章:
- 多态性和功能结合
- 具有默认模板参数的多态类的模板推导失败
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 多态二进制函数
- 访问存储在向量C++中的结构的多态成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 多态性需要分配
- 如何为多态性中的指定类型分配内存
- 分配分配器为多态对象分配内存
- 通过指向非多态类型的基类的指针获取已分配内存的地址
- 当我需要多态性时,如何避免动态分配
- 返回不带动态内存分配的多态类型
- 动态分配和多态性-c++
- 在特定位置分配多态类成员
- 分配给派生类和多态性的基类指针
- 删除使用placement new分配的动态多态对象
- 在运行时将指针分配给多态类
- shared_ptr成员变量的多态分配
- c++使用RAII与多态性和堆栈分配