表示类型的变量?运行时的继承

variable representing type? inheritance at runtime?

本文关键字:运行时 继承 变量 类型 表示      更新时间:2023-10-16

我问这个问题的原因:我使用的是一个不是我自己设计的大框架。我需要使用几个与代码无关的"用户信息"类。它们不是从任何公共基类派生的,我也没有权限重新编译源代码。

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

问题是,我想为Ainfo、Binfo、Cinfo、Dinfo等做这件事。所以我想写一个mixin或一些东西,只将容器功能添加到任何普通的旧信息类中。

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

所以问题是:

是否可以将类型向量传递到mixin的构造函数中?这样,我就可以传入一个适当构造函数参数的变量列表?你能给模板参数之外的变量赋值吗?你能用这个变量进行强制转换吗?

是否可以从特定对象继承?例如,我可以使用正确的构造函数创建一个新的Ainfo对象,然后对该特定对象进行混合吗。这就像decorator模式的用法一样,只是我没有公共接口。(被装饰的对象是接口)

我是不是要咬紧牙关写15000个(夸张地说:)类,它们完全相同,但从不同的基类继承,并包含不同类型的对象?

摘要:

我需要为几个不同的类添加一个容器特性,同时维护每个类的接口并利用它们的参数接受构造函数。我不想重复代码。

提前谢谢。很抱歉完全是屠杀术语。

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

例如,您可以这样做:

typedef boost::variant<Ainfo, Binfo, Cinfo> CommonInfo;
//In a function.
CommonInfo someInfo = Ainfo();

然后,您可以编写访问者函数,这些函数可用于调用info对象的成员。

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,那么您可以使用它。你可以为这些访客建造一套套房;它们可以返回值、获取参数(尽管您需要将它们存储在functor中),以及您可以从文档中学习的各种其他技巧。

如果它在模板中不可行,而且你不能用预处理器破解它,那么你就必须手工完成。C++在运行时不包含任何类型操作,只有typeid()dynamic_cast

这可能有点过于简单化,但如果没有其他内容,它应该有助于澄清您的问题。使用模板,您可以轻松地生成从信息类派生的类。下面的类说明了这个概念。

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();

我可能错了,但我有一种感觉,我们现在离得很近了。。。