打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C++怎么在运行时动态创建类?
我是想这样,比如如下代码:
class A{
int a1,a2,a3;
fa1(){}
fa2(){}
fa3(){}
};
class B{
int b1,b2,b3;
fb1(){}
fb2(){}
fb3(){}
}
然后我想在运行时创建一个类
class C{
int c1,c2;
fa1(){};// 假设为无参数, 同class A中的fa1
fb2(){};//假设为无参数, 同class B中的fb2
};
然后还可以根据这个新建的类,在运行时动态的创建对象:
C c1,c2;
回答一:
哦,原来楼主是这个意思,领会错了。
动态创建类的数据类型,这个是可行得通的,只不过样子不是你想象的那样,
见下面,以int和char为例的代码。
新类的以字节的形式存放在binaryClassData里面,只是访问起来比较费劲。
C/C++ code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
struct BaseValue
{
union
{
int intValue;
char charValue;
}  value;
};
class CDynObj
{
public:
char * binaryClassData;
int   length;
vector<string>  fieldInfos;
vector<int>     fieldPos;
BaseValue getFieldValue(int i)
{
BaseValue value;
if( fieldInfos.at(i)=="int" )
{
value.value.intValue= *( (int*)(binaryClassData+fieldPos[i]) );
}else if( fieldInfos.at(i)=="char" )
{
value.value.charValue = *( (char*)(binaryClassData+fieldPos[i]));
}
return value;
}
void setFieldValue(int i, BaseValue)
{
//省略
}
};
class CCreateNewObj
{
public:
CCreateNewObj():obj(NULL)
{
}
CDynObj * obj;
int getCurrentLength()
{
int offset = 0;
for( int i=0; i<obj->fieldInfos.size(); ++i )
{
string &fld = obj->fieldInfos.at(i);
int temp = 0;
temp =( fld=="int"?4:1 );
offset += temp;
}
return offset;
}
void addType( string type)
{
if( obj == NULL )
{
obj = new CDynObj();
}
int offset = getCurrentLength();
obj->fieldPos.push_back( offset );
obj->fieldInfos.push_back(type);
}
CDynObj * createObject()
{
int l = getCurrentLength();
obj->length = l;
obj->binaryClassData = new char[l];
}
};
有没有办法在运行时调用“已定义的类”中的代码重新创建一个新的类呢?
这个实现起来也可以,大不了把this封装成一个类,运行的时候才确定到底是啥值,麻烦了些。
虽然函数接收this指针,但是每个this指针访问其内部成员变量的时候,每个类的内存布局都是不一样的,
按照楼主的要求,这些都不是不能在编译阶段确定的,必须在运行时候才能确定下来,
所以不能直接进入其他类的成员函数,即使把this换换都不行。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
回答二:
楼主似乎是想在C++里面实现类似Java语言的Class.forName("className")这样的类动态加载机制吧?这种机制允许代码装载一个代码中不存在的类,并且可以创建这个类的实例。C++语言本身是没有这个机制的。不过在特定的平台下实现动态的实例化一个未静态链接到代码中的类倒是有可能的。
实现思路就是为每个需要动态实例化的类设计一个类加载器,需要动态实例化的类放在一个DLL中(适用于Windows平台,DLL文件名可以与类名相同),这个DLL还提供一个createInstance接口,用于向类加载器返回动态创建的类实例。然后类加载器在运行时刻装载DLL,并且调用createInstance接口即可实现类实例的动态创建。用这种方法,原代码中可以不必链接被装载类的任何代码,可以根据类名字符串动态地创建这个类的实例。这种方法的限制是消费者代码中必须包含被装载类的基类的信息。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
回答三:
LZ的想法可能是,在做C类时不知道有A, B...其它类,但是为了需要可能要调用未知类的方法,这属于类成员方法指针的问题,可以参考:http://blog.csdn.net/kyee/archive/2009/03/20/4009735.aspx
C/C++ code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* TObject - 基类 */
class TObject
{
};
/* TDemoA - A 类 */
class TDemoA
{
public:
TDemoA();
virtual ~TDemoA();
void  AF1(void* AParam);
void  AF2(const char* AStr, long AValue);
// ??? ... ...
};
/* TDemoB - B 类 */
class TDemoB
{
public:
TDemoB();
virtual ~TDemoB();
void  BF1(void* AParam);
void  BF2(const char* AStr, long AValue);
// ??? ... ...
};
/* TDemoC - C 类 */
class TDemoC
{
public:
// TOnFunc1 事件类型
typedef void (TObject::*TDoFunc1)(void* AParam);
typedef struct
{
TDoFunc1          Method;
void*             Object;
} TOnFunc1;
// TOnFunc2 事件类型
typedef void (TObject::*TDoFunc2)(const char* AStr, long AValue);
typedef struct
{
TDoFunc2          Method;
void*             Object;
} TOnFunc2;
public:
TDemoC();
virtual ~TDemoC();
// Func1
void  Func1(void* AParam)
{
if (OnFunc1.Method != NULL)
((TObject*)OnFunc1.Object->*OnFunc1.Method)(AParam);
}
// Func2
void  Func2(const char* AStr, long AValue)
{
if (OnFunc2.Method != NULL)
((TObject*)OnFunc2.Object->*OnFunc2.Method)(AStr, AValue);
}
// 事件
TOnFunc1    OnFunc1;
TOnFunc1    OnFunc2;
};
// 例子
TDemoA A;
TDemoB B;
TDemoC C;
int demo()
{
// ??? ... ...
C.OnFunc1.Object  = &B;
C.OnFunc1.Method  = (TDemoC::TDoFunc1)&TDemoB::BF1;
C.OnFunc2.Object  = &A;
C.OnFunc2.Method  = (TDemoC::TDoFunc2)&TDemoA::AF2;
// 调用 C 方法
C.Func1(...);     // <=> B.BF1(...);
C.Func2(...);     // <=> A.AF2(...);
// ??? ... ...
C.OnFunc1.Object  = &A;
C.OnFunc1.Method  = (TDemoC::TDoFunc1)&TDemoA::AF1;
C.OnFunc2.Object  = &B;
C.OnFunc2.Method  = (TDemoC::TDoFunc2)&TDemoB::BF2;
// 调用 C 方法
C.Func1(...);     // <=> A.AF1(...);
C.Func2(...);     // <=> B.BF2(...);
// ??? ... ...
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
其它回答:
我看明白楼主的意思了  楼主的意思是代码中没有这个类   到了运行时根据其它类合成一个新类……
C++中是不可能的,希望有生之年可以看到有种语言实现这种功能答:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C++现在还没有支持这样的功能,类模板和楼主说的或许有点想。但也不是一个意思。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
嘿嘿,是这样子。
有没有可能用指针跳转来模拟呢?
C++的对象不是根据this指针跳转到类中的函数吗?就是好像一个this指针不能被带到多个类中,郁闷。。。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java的Class.forName("className")这个className必须是在编译期间预先定义好的,
否则就是 ClassNotFoundException
Java是用Reflection来处理lz的要求的(一个Object,和一个类的描述符Class)。
实际上这些C++都可以实现的。比如类似Class.forName,早在MFC里面微软就用C++实现了。
唯一困难的是lz想重入别人的类的代码。这个涉及到对象的内存布局,基本上不现实。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
或许是因为C++是面向对象的,只有对象可以被改变,要在运行时改变类型,需要面向类型才行,这说明在C++上面还可以有个壳,专门处理类型的语言。
现在有没有呢?
其他的语言我不熟悉,就看过C和C++,好像少了点。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
只要能自由操作内存,一切皆有可能
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这是个设计问题,要细化设计的粒度。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
但是好像 C++ 里面,并不会很好用,, 毕竟它不像JAVA有反射的办法,,
如果要彻底好用,,那只能用 17楼的办法,,把不同的实现,放到不同的dll里面,就可以动态的调用不同的实现类了,,但又有一个问题了, 每个 dll 都要有相同的界面,
所以啊 C++ 出不了像 spring的框架。。  语言特性限制了。??  不晓得说的对不对。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
楼主似乎是想在C++里面实现类似Java语言的Class.forName("className")这样的类动态加载机制吧?这种机制允许代码装载一个代码中不存在的类,并且可以创建这个类的实例。C++语言本身是没有这个机制的。不过在特定的平台下实现动态的实例化一个未静态链接到代码中的类倒是有可能的。
实现思路就是为每个需要动态实例化的类设计一个类加载器,需要动态实例化的类放在一个DLL中(适用于Windows平台,DLL文件名可以与类名相同),这个DLL还提供一个createInstance接口,用于向类加载器返回动态创建的类实例。然后类加载器在运行时刻装载DLL,并且调用createInstance接口即可实现类实例的动态创建。用这种方法,原代码中可以不必链接被装载类的任何代码,可以根据类名字符串动态地创建这个类的实例。这种方法的限制是消费者代码中必须包含被装载类的基类的信息。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Cython 中的类型转换
C++
vc++6.0 编译JRTPLIB
关于回调函数和this指针探讨
C ++ 中对象或其对象指针的赋值
如何理解父类引用指向子类对象
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服