表示类型的变量?运行时的继承
variable representing type? inheritance at runtime?
我问这个问题的原因:我使用的是一个不是我自己设计的大框架。我需要使用几个与代码无关的"用户信息"类。它们不是从任何公共基类派生的,我也没有权限重新编译源代码。
这些信息类的工作方式如下:有类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();
我可能错了,但我有一种感觉,我们现在离得很近了。。。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 我在c++代码中生成了一个运行时#3异常
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 建议在运行时将带有类实例的列表从c++导入qml
- 在运行时检查继承是否只有一种类型和 void*
- 无法从网页类继承而不出现运行时错误
- 运行时动态绑定和类继承之间的区别
- 运行时绑定和虚拟继承
- 如何在运行时搜索C++中的继承树
- 继承编译时或运行时
- 具有多重继承的消息映射MFC:如何避免警告C4407和运行时崩溃
- 表示类型的变量?运行时的继承
- 在运行时使用继承的代码选择器