我试图在Delphi中将对象解析为XML,所以我读到了调用对象的ClassInfo方法以获取其RTTI信息.
问题是,这显然只适用于TPersistent对象.否则,我必须在编译器的源代码中专门添加编译器指令{$ M +}以生成RTTI信息.
所以我很高兴地添加了该指令,只是为了发现它,即使它确实从ClassInfo调用返回了一些东西(它曾经返回nil),现在我无法从中检索类的属性,字段或方法.这就像它创建了对象为空.
知道我在这里缺少什么吗?谢谢!
我的C++有点生疏.这是我正在尝试做的事情:
class Cmd { };
class CmdA : public Cmd { };
class CmdB : public Cmd { };
...
Cmd *a = new CmdA ();
Cmd *b = new CmdB ();
Run Code Online (Sandbox Code Playgroud)
第一个问题:
cout << typeid (a).name ()
cout << typeid (b).name ()
Run Code Online (Sandbox Code Playgroud)
两者都返回Cmd*类型.我想要的结果是CmdA*和CmdB*.除此之外的任何方式实现此目的:
if (dynamic_cast <CmdA *> (a)) ...
Run Code Online (Sandbox Code Playgroud)
其次,我想做这样的事情:
class Target {
public:
void handleCommand (Cmd *c) { cout << "generic command..." }
void handleCommand (CmdA *a) { cout << "Cmd A"; }
void handleCommand (CmdB *b) { …Run Code Online (Sandbox Code Playgroud) TBaseClass = class
public
destructor Destroy; override;
end;
TFirstClass = class(TBaseClass)
FMyProp: string;
end;
TSecondClass = class(TBaseClass)
FMyFirstClass: TFirstClass;
end;
Run Code Online (Sandbox Code Playgroud)
我需要实现一个DESTRUCTOR,它能够从同一个基类中找到所有(对象类型)字段并给它一个Free来避免所有这些内存泄漏.
为什么?因为FMyFirstClass可以创建或不创建,这取决于我的应用程序的流程,我无法保证何时将其创建为Free it,既不想用NIL检查所有析构函数来检查代码,因为我有一个很多像这样的领域.
我正在尝试使用新的RTTI来获取基于TBaseClass的所有字段,但我无法获得对象字段的实例,而且我没有想法.
我会走正路吗?你建议做什么?
我需要浏览一些类的所有已发布属性.未列出类型为具有固定值的枚举的属性.
见下面的例子:
TMyEnum = (meBlue, meRed, meGreen);
TMyEnumWithVals = (mevBlue=1, mevRed=2, mevGreen=3);
TMyClass =
...
published
property Color: TMyEnum read FColor write SetColor; // This one is found
property ColorVal: TMyEnumWithVals read FColorVal write SetColorVal; // This one is never found
end;
Run Code Online (Sandbox Code Playgroud)
我需要固定值,因为这些属性存储在数据库中,我需要确保分配的值始终是相同的,无论下一版本中的Delphi编译器选择如何,并防止在枚举列表中任何错误的未来值插入.
我尝试使用新的Delphi 2010 RTTI(带.GetDeclaredProperties)和"旧"RTTI(带GetPropInfos):除上述类型的属性外,找到所有属性.
在所有类中都可以看到相同的行为.我还在一个示例项目中复制了这个.
尝试使用和不使用各种RTTI指令而不进行更改.
这是一个错误,一个已知的限制?是否有解决方法(除了删除枚举的固定值)?
使用Delphi2010 Ent + Update5
[编辑]答案下面提供变通方法:枚举的第一个值必须被设置为0而不是1,和值是连续的.经过测试和工作的解决方案
谢谢,
我正在使用Delphi XE编写基类,这将允许降序类通过应用注释来映射dll方法.但是我得到了一个类型转换错误,这是可以理解的.
本质上,基类应如下所示:
TWrapperBase = class
public
FLibHandle: THandle;
procedure MapMethods;
end;
procedure TWrapperBase.MapMethods;
var
MyField: TRttiField;
MyAttribute: TCustomAttribute;
pMethod: pointer;
begin
FLibHandle := LoadLibrary(PWideChar(aMCLMCR_dll));
for MyField in TRttiContext.Create.GetType(ClassType).GetFields do
for MyAttribute in MyField.GetAttributes do
if MyAttribute.InheritsFrom(TMyMapperAttribute) then
begin
pMethod := GetProcAddress(FLibHandle, (MyAttribute as TMyMapperAttribute).TargetMethod);
if Assigned(pMethod) then
MyField.SetValue(Self, pMethod); // I get a Typecast error here
end;
Run Code Online (Sandbox Code Playgroud)
降序类看起来像这样:
TDecendant = class(TWrapperBase)
private type
TSomeDLLMethod = procedure(aParam: TSomeType); cdecl;
private
[TMyMapperAttribute('MyDllMethodName')]
FSomeDLLMethod: TSomeDLLMethod;
public
property SomeDLLMethod: TSomeDLLMethod read FSomeDLLMethod;
end; …Run Code Online (Sandbox Code Playgroud) 我有一个基类和n派生类.我想实例化一个派生类并将其发送到一个接收基类作为参数的函数.在函数内部,我通过使用dynamic_cast找到了哪种类型的派生类,但我不想使用几个if-else语句.相反,我想知道是否有办法找出哪个派生类是为了投出它.这里我以我的代码为例.
class animal{
public:
virtual ~animal() {}
int eyes;
};
class dog: public animal{
public:
int legs;
int tail;
};
class fish: public animal{
public:
int mostage;
};
void functionTest(animal* a){
if(dynamic_cast<fish*>(a) != NULL){
do_something();
}
else if(dynamic_cast<dog*>(a) != NULL){
do_something();
}
};
Run Code Online (Sandbox Code Playgroud)
我想对此有一个更一般的方法.像dynamic_cast(a)这样的东西.谢谢!
我需要使用RTTI遍历具有复杂结构的类.该类有几个记录成员,我也想迭代.
TRTTIHelpers<T> = class
public
class function DoGetValuesForClass(aClassInst: T): TStringList;
class function DoGetValuesForRecord(aRec: T): TStringList;
end;
Run Code Online (Sandbox Code Playgroud)
我知道当我在课堂上有一个成员时,这是一个记录:
for prop in rt.GetProperties() do
begin
if prop.PropertyType is TRttiRecordType then
begin
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(TValue)); <--
end
Run Code Online (Sandbox Code Playgroud)
如何将TValue作为参数传递给DoGetValuesForRecord,以便我也可以遍历记录?
当我分配一个TDateTime值,以OleVariant使用RTTI的对象的属性,对象变为浮点值.
对象的设计使得此属性可以变为Null或任何数据类型的值.如果它变为浮点数,则应将结果计算为浮点数的差值.如果变为TDateTime,则应将结果计算为两个TDateTime值的差值.
我是否已将值直接传递给它,它会正常工作,但中间有RTTI.
我知道TDateTime内部重新设置为float,但有可能接收到我发送的数据类型吗?
请看tkVariant以下代码示例中的案例:
class procedure TRTTI.SetObjPropValue(obj: TObject; rprop: TRttiProperty; value: OleVariant);
var
rtyp: TRttiType;
vt: TVarType;
begin
if obj = nil then Exit();
if (rprop <> nil) and (rprop.IsWritable) then begin
case rprop.PropertyType.TypeKind of
tkInteger, tkInt64:
begin
value := TVarConv.NullableCurr(value);
if VarIsNumeric(value) then rprop.SetValue(obj, TValue.FromVariant(Trunc(value)));
end;
tkFloat:
begin
if rprop.PropertyType.Name = 'TDateTime' then
value := TVarConv.NullableDateTime(value)
else
value := TVarConv.NullableFloat(value);
if not VarIsNull(value) then rprop.SetValue(obj, TValue.FromVariant(value)); …Run Code Online (Sandbox Code Playgroud) 我想知道是否可以使用RTTI来使用其名称(以字符串形式传递)来获取静态方法/函数指针
到目前为止,我有以下代码:
#include <map>
int Foo() {
return 42;
}
int Bar() {
return 117;
}
typedef int (*function_ptr)();
int main() {
std::map<std::string, function_ptr> fctmap;
fctmap["Foo"] = Foo;
fctmap["Bar"] = Bar;
}
Run Code Online (Sandbox Code Playgroud)
就我而言,这种设置和保持函数指针手动映射的方法非常不雅致。有没有一种“自动”方式?
我遇到了一段代码,typeid用来获取unique_ptr指向多态对象的类型。
class B{virtual void foo()= 0;};
class D:public B{void foo() override{}};
int main()
{
unique_ptr<B> bd = make_unique<D>();
if (typeid(*bd) != typeid(bd.get()))
{
cout<<"Object types are not same"<<endl;
}
cout<<"Type name of *bd.name(): "<<typeid(*bd).name()<<endl;
cout<<"Type name of bd.get().name(): "<<typeid(bd.get()).name()<<endl;
}
Run Code Online (Sandbox Code Playgroud)
输出为:
Object types are not of same
Type name of *bd.name(): 1D
Type name of bd.get().name(): P1B
Run Code Online (Sandbox Code Playgroud)
get()的输出与使用*取消引用的输出name()不同。另一个观察结果是,当类中没有定义虚函数时(上述示例中没有),get()和*都打印相同的输出。void foo()
问题:
当类中没有虚函数时,为什么get()和*给出不同的输出?
实时示例:https : //gcc.godbolt.org/z/Tiy-Cn
EDIT-1根据unique_ptr上的*,它说“返回* this拥有的对象,等效于* get()。”
rtti ×10
delphi ×6
c++ ×4
inheritance ×2
annotations ×1
c++11 ×1
datetime ×1
delphi-xe ×1
oop ×1
typeid ×1
unique-ptr ×1
variant ×1