变量代表类型?在运行时继承?

时间:2011-06-21 18:00:01

标签: c++ interface types runtime mixins

我提出问题的原因是: 我使用的是不属于我自己设计的大型框架。我需要使用几个与用户无关的“用户信息”类。它们不是从任何公共基类派生的,我无权访问要重新编译的源代码。

这些信息类的工作方式如下:有A,B,C等类。这些类都有一个与之关联的信息类Ainfo,Binfo等。因为用户(即我)需要将不同的信息附加到给定类的给定对象(意味着我可能有两个不同的类派生自Ainfo,我想附加到A的对象),并且只有一个信息槽,我想制作一个可以旧的其他各种信息对象的信息对象。这样,我就可以将我的信息添加到这个虚假的信息对象中 - 这是一个容器,用于其他信息对象。

问题在于我想为Ainfo,Binfo,Cinfo,Dinfo等做这个。所以我想写一个mixin或者只是将容器功能添加到任何普通的旧信息类中。< / p>

问题是信息类Ainfo,Binfo等需要不同的构造函数参数。

所以问题是:

是否可以将类型向量传递给mixin的构造函数?这样我可以传入适当的构造函数参数的变量列表?你可以在模板参数之外的变量中指定一个类型吗?你可以使用这个变量进行投射吗?

是否可以从特定对象继承?我可以使用正确的构造函数创建一个新的Ainfo对象,然后对该特定对象执行mixin。这就像装饰器模式的用法,除了我没有通用接口。 (正在装饰的对象是界面)

我是否只需要咬紧牙关并编写完全相同的15,000(夸大:))类,但是从不同的基类继承并包含不同类型的对象?

要点:

我需要为几个不同的类添加容器功能,同时保持每个类的接口并利用他们的参数构造器。我想不重复代码。

提前致谢。对不起完全屠宰术语。

3 个答案:

答案 0 :(得分:2)

听起来像你想要的是Boost.Variant。它就像一个C ++风格的联盟。它是强类型的(这样你总能知道它实际存储在它中的内容),它有一个强大的访问机制,可以很容易地将许多不同的类型映射到一个操作。

例如,您可以这样做:

typedef boost::variant<Ainfo, Binfo, Cinfo> CommonInfo;

//In a function.
CommonInfo someInfo = Ainfo();

然后,您可以编写可用于调用信息对象成员的访问者仿函数。

class DoThingInfoVisitor : boost::static_visitor<>
{
    void operator()(Ainfo &info) {info.DoThing()}
    void operator()(Binfo &info) {info.DoThing2()}
    void operator()(Cinfo &info) {info.StepA(); info.StepB();}
};

有了这个对象,如果你想做任何这个DoThing对任何CommonInfo类型的意义:

CommonInfo someInfo = Ainfo();
boost::apply_visitor( times_two_visitor(), someInfo );

这会调用Ainfo版本,因为这就是someInfo中存储的内容。如果它已存储Binfo,那么您可以使用它。你可以建立一套这样的访客;他们可以返回值,获取参数(虽然您需要将它们存储在仿函数中),以及您可以从文档中学习的各种其他技巧。

答案 1 :(得分:1)

如果在模板中不可行,并且您无法使用预处理器破解它,那么您将不得不手动完成。 C ++在运行时不包含任何类型操作,typeid()dynamic_cast就是你所拥有的。

答案 2 :(得分:1)

这可能有点过于简单化,但如果没有别的,那么它应该有助于澄清你的问题。使用模板,您可以轻松生成派生自您的信息类的类。以下课程说明了这一概念。

class Ainfo {
  std::string _a;
public:
  void setContent(const std::string& A);
  const char * print() const; // prints _a
};

class Binfo {
  std::string _b;
public:
  void setContent(const std::string& B);
  const char * print() const; // prints _b
};

template<class Tinfo>
class Info : public Tinfo {
};

然后您可以按如下方式使用此模板。

Info<Ainfo> my_info;
my_info.setContent("test");
std::cout << my_info.print();

更新:如果您还想覆盖模板的构造函数,请尝试使用成员模板。

template<class Tinfo>
class Info : public Tinfo {
public:
    template<typename arg>
    Info(arg rhs) : Tinfo(rhs) { }
};

使用它,您可以编译并运行以下内容。

Info<Ainfo> my_info("Testing...");
std::cout << my_info.print();

我可能错了,但我觉得我们现在已经相当接近......