C++动态类(动态黑客)
C++ dynamic class ( dynamic hack )
有没有办法在运行时将字段添加到类(以前不存在的字段)?像这样的片段:
Myobject *ob; // create an object
ob->addField("newField",44); // we add the field to the class and we assign an initial value to it
printf("%d",ob->newField); // now we can access that field
我真的不在乎它会怎么做,我不在乎它是否是一个丑陋的黑客,我想知道它是否可以完成,以及一个小例子,如果可能的话。
另一个例子:假设我有一个描述这个类的XML文件:
<class name="MyClass">
<member name="field1" />
<member name="field2" />
</class>
我想将字段"field1"和"field2"添加到类中(假设该类已经存在)。假设这是类的代码:
class MyClass {
};
我不想在运行时创建一个类,我只想在现有的一个类中添加成员/字段。
谢谢!
使用地图和变体。
例如,使用 boost::variant。请参阅 http://www.boost.org/doc/libs/1_36_0/doc/html/variant.html
(当然,您可以创建自己的属性,以适应 XML 属性的类型。
#include <map>
#include <boost/variant.hpp>
typedef boost::variant< int, std::string > MyValue ;
typedef std::map<std::string, MyValue> MyValueMap ;
通过将 MyValueMap 添加为类的成员,可以根据属性的名称添加属性。这意味着代码:
oMyValueMap.insert(std::make_pair("newField", 44)) ;
oMyValueMap.insert(std::make_pair("newField2", "Hello World")) ;
std::cout << oMyValueMap["newField"] ;
std::cout << oMyValueMap["newField2"] ;
通过将其封装在 MyObject 类中,并在此 MyObject 类中添加正确的重载访问器,上面的代码变得更加清晰:
oMyObject.addField("newField", 44) ;
oMyObject.addField("newField2", "Hello World") ;
std::cout << oMyObject["newField"] ;
std::cout << oMyObject["newField2"] ;
但是你在某种程度上失去了C++这样做的类型安全性。但是对于XML,我想这是不可避免的。
没有办法按照你描述的方式做到这一点,因为编译器需要在编译时解析引用 - 它会生成错误。
但请参阅通用设计模式。
你不能使该语法起作用(因为在编译时进行静态检查),但如果你愿意修改语法,你可以很容易地达到同样的效果。拥有一个具有字符串>blob映射的字典成员并具有如下成员函数是相当容易的:
template< typename T > T get_member( string name );
template< typename T > void set_member( string name, T value );
如果需要,可以使语法更紧凑/棘手(例如:使用"->"运算符覆盖)。您还可以利用一些特定于编译器的技巧(例如,MSVC 支持 __declspec(属性),它允许您将对成员变量的引用映射到特定格式的方法)。但是,归根结底,您将无法执行编译器在该语言中不接受的操作并对其进行编译。
简短版本:做不到。对此没有本机支持,c ++是静态类型的,编译器必须知道要操作的每个对象的结构。
建议:使用嵌入式中间处理器。并且不要编写自己的(见下文),获取一个已经工作和调试的。
您可以做什么:实现足够的中间处理器以满足您的需求。
使用数据成员设置类非常简单,例如
std::vector<void*> extra_data;
您可以在运行时将任意数据附加到其中。这样做的成本是您必须使用以下方法手动管理该数据:
size_t add_data_link(void *p); // points to existing data, returns index
size_t add_data_copy(void *p, size_t s) // copies data (dispose at
// destruction time!), returns
// index
void* get_data(size_t i); //...
但这不是限制,只要多加小心,您可以将任意数据与名称相关联,并且可以根据需要继续详细说明此方案(添加类型信息等),但这归结为实现一个中间器来处理您的运行时灵活性。
否 -- C++不支持像这样对类型系统进行任何操作。 即使是具有一定程度运行时反射的语言(例如 .NET)也不会完全支持这种范式。 你需要一种更动态的语言才能做到这一点。
我正在看这个,我做了一些搜索,这个代码片段来自: 迈克尔·哈默的博客似乎是做到这一点的好方法,通过使用 boost::any
首先,定义一个结构,该结构定义一个包含键(即变量名)和值的 std::map。定义了一个函数来广告对,并将其与一个函数一起设置以获取值。如果你问我,这很简单,但在做更复杂的事情之前,这似乎是一个很好的开始方式。
struct AnyMap {
void addAnyPair( const std::string& key , boost::any& value );
template<typename T>
T& get( const std::string key ) {
return( boost::any_cast<T&>(map_[key]) );
}
std::map<const std::string, boost::any> map_;
};
void AnyMap::addAnyPair( const std::string& key , boost::any& value ) {
map_.insert( std::make_pair( key, value ) );
}
最重要的是,这是一个黑客,因为C++是严格的类型检查语言,因此对于那些扭曲规则的人来说,怪物就在里面。
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- C++中的动态铸造故障
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 控制允许动态运行c++的并发操作数
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 输出没有重复元素的动态数组(收缩数组)C++
- C++为线程工作动态地分割例程
- 正在插入动态数组
- 黑客级别的Mini-Max Sum
- 在c++中使用动态分配的问题
- C++中的动态对象与非动态对象
- 如何在动态数组上使用搜索函数
- 视觉studo 2019中的漫画和静态/动态绑定
- 从C++中的数字输入动态创建矩阵
- 如何从QToolBox中动态创建的QLineEdit中获取文本
- C++动态类(动态黑客)