我会自己回答这个问题,但如果你比我快,或者你不喜欢我的解决方案,请随时提供你的答案.我想出了这个想法,并希望对此有一些看法.
目标:一个可读的配置类(如INI文件),但无需编写(并在添加新配置项后进行调整)加载和保存方法.
我想创建一个类
TMyConfiguration = class (TConfiguration)
...
property ShowFlags : Boolean read FShowFlags write FShowFlags;
property NumFlags : Integer read FNumFlags write FNumFlags;
end;
Run Code Online (Sandbox Code Playgroud)
调用TMyConfiguration.Save(继承自TConfiguration)应该创建一个类似的文件
[Options]
ShowFlags=1
NumFlags=42
Run Code Online (Sandbox Code Playgroud)
问题:最好的方法是什么?
Andrei Alexandrescu在Modern C++ Design中写道:
返回的对象
typeid具有静态存储,因此您不必担心生命周期问题.
安德烈继续说:
标准并不保证每次调用都会
typeid(int)返回对同一type_info对象的引用 .
即使标准不能保证这一点,如何在常见的编译器中实现,例如GCC和Visual Studio?
假设typeid没有泄漏(并且每次调用都返回一个新实例),每个应用程序,每个翻译单元,每个dll/so或者完全不同的东西,它是一个"表"吗?
有时间&typeid(T) != &typeid(T)吗?
我主要对Windows的编译器感兴趣,但是对于Linux和其他平台的任何信息也很感激.
我最近使用了delphi xe,但由于rtti(我认为),exe大小非常大
如何删除rtti,我可以使我的应用程序大小与delphi 2009应用程序(490 kb)一样小,没有comprssion; 什么是rtti的用途
我有一个类层次结构,如下所示:
class A { } //
class AA : A { } // A
class AAA : AA { } // / \
class AAB : AA { } // AA AB
class AB : A { } // / \ / \
class ABA : AB { } // AAA AAB ABA ABB
class ABB : AB { } //
Run Code Online (Sandbox Code Playgroud)
我想为这个ierarchy模拟RTTI(当然不使用它),在给定指针/引用的情况下A,我可以找到它的实际类型(类似于什么typeid),作为一个标识类.
此外,我希望识别我的类型的整数集合是连续的,从0到N-1(在我的例子中从0到6):
class A { virtual int t(){return 0;} } //
class AA : A …Run Code Online (Sandbox Code Playgroud) 我已经存储了一个指向type_info对象的指针.
int MyVariable = 123;
const std::type_info* Datatype = &typeid(MyVariable);
Run Code Online (Sandbox Code Playgroud)
我如何使用它来将另一个变量强制转换为该类型?我试过这个,但它不起作用:
std::cout << ((*Datatype)3.14) << std::endl;
Run Code Online (Sandbox Code Playgroud)
使用类型转换的函数形式不起作用:
std::cout << (*Datatype(3.14)) << std::endl;
Run Code Online (Sandbox Code Playgroud) 我想使用RTTI在设计时而不是运行时检查项目源文件中包含的类型.
据我所知,这是不受支持的,但是这个问题的评论中的讨论表明它可能并且已经有几个Delphi版本.这是我第一次听说这个功能可用但是我一直无法为自己重现它.
这是我的测试示例.它使用一个简单的TListBox后代TMyListBox,它具有一个string属性TypeToExplore,该属性在设置时使用输入的限定类型名称的属性填充列表框.
unit MyListBox;
interface
uses
SysUtils, Classes, Controls, StdCtrls;
type
TMyListBox = class(TListBox)
private
FTypeToExplore : string;
procedure SetTypeToExplore(const inValue: string);
procedure FillWithTypeDetails;
published
property TypeToExplore : string read FTypeToExplore write SetTypeToExplore;
end;
procedure Register;
implementation
uses
RTTI, TypInfo;
procedure TMyListBox.SetTypeToExplore(const inValue: string);
begin
if inValue = FTypeToExplore then
Exit;
FTypeToExplore := inValue;
Clear;
FillWithTypeDetails;
end;
procedure TMyListBox.FillWithTypeDetails;
var
context : TRTTIContext;
theType : TRttiType;
properties …Run Code Online (Sandbox Code Playgroud) 我最近在某个论坛上看到了一个OO设计问题,并开始考虑使用RTTI.然而,这一定是糟糕的设计,但我无法想到另一种选择.这是一个简单的问题:
使用OO概念为以下场景创建C++程序 -
我的名叫巴迪的狗住在后院.晚上,当他看到一只猫或一只来看望的松鼠时,他会吠叫.如果他看到一只青蛙,并且他饿了,他就会吃掉它.如果他看到一只青蛙并且他不饿,他就会玩它.如果他已经吃了2只青蛙,并且仍然感到饥饿,他会放手.如果他看到一只土狼,他会求助.有时他的朋友Spot停了下来,他们互相追逐.如果他看到任何其他动物,他只是看着它.我希望你会有一个动物类,一只猫,狗,松鼠,土狼类继承自动物类.
我开始考虑在dog类中使用一个see()方法,该方法接受一个Animal参数然后检查对象的实际类型(青蛙,猫等)并采取所需的操作 - 根据实际类型进行游戏,追逐等.然而,这将需要RTTI,这必须是糟糕的设计.任何人都可以建议一个更好的设计,这将避免RTTI,并指出我的想法中的错误?
它是否意味着保证相同的std::type_info::hash_code()值意味着相同的类型?
Cplusplus.com似乎声称:
此函数为任何两个比较相等的type_info对象返回相同的值,而不同的值则返回不同的值.[强调我的]
Cppreference似乎另有说法:
返回一个未指定的值,对于对象,它引用相同的类型.没有给出其他保证,特别是,值可以在同一程序的调用之间改变.[强调我的]
相关标准段落是:
§p18.7.1p7-8
size_t hash_code()const noexcept;
7返回:一个未指定的值,除了在程序的单次执行中,它应为任何两个比较相等的type_info对象返回相同的值.
8备注:实现应为两个不比较相等的type_info对象返回不同的值.[强调我的]
" 应该 "应该在上面的语境中是什么意思?如果段落8是一个要求,那么似乎不可能实现,除非运行时对程序中的所有符号名称进行某种全局统一以确保缺少哈希冲突,这似乎是标准的一个相当大的负担强加于实现,特别是对于一个被调用的函数hash_code().(Itanium实际上需要这个,但它显然是高于标准的额外要求.)
如果" 应该 "并不意味着具有约束力,那么这句话似乎是毫无意义的,也就是标准中的缺陷,因为要求实现尝试满足一个无法依赖的困难要求,不会产生任何价值,只会引起混淆和碎片化.任何人都知道为什么会这样吗?
编辑:也许"缺陷"太强了,但至少它是一个可能混淆的点,应该澄清,因为它显然误导了至少一个参考网站,并传递误导任何依赖它的人.此外,它实际上是可能实现的要求(只要受实现支持的类型的数量比范围更小size_t),如果全球uniquing是在运行时完成,如果标准是试图表明这为目前还不清楚理想的实施策略与否.
我正在尝试仅为我的类的子集启用RTTI.
原因是对于那些我想要RTTI的类,我也想在公共方法上使用RTTI,但如果在项目范围内启用它,那么所有类的所有公共方法都会进入最终的可执行文件.这基本上关闭了智能链接,因为编译器认为每个公共方法都可以在运行时调用,因此最终编译几乎所有东西,厨房沉入可执行文件......
我尝试了几件事:
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}然后为相关单元重新启用它会导致在$ RTTI指令的编译时(编译器中某处的AV)崩溃.还有其他想法吗?
我有这个代码:
class Class {
public:
virtual void first() {};
virtual void second() {};
};
Class* object = new Class();
object->first();
object->second();
delete object;
Run Code Online (Sandbox Code Playgroud)
用Visual C++ 10和/ O2编译并进行反汇编:
282: Class* object = new Class();
00403953 push 4
00403955 call dword ptr [__imp_operator new (4050BCh)]
0040395B add esp,4
0040395E test eax,eax
00403960 je wmain+1Ch (40396Ch)
00403962 mov dword ptr [eax],offset Class::`vftable' (4056A4h)
00403968 mov esi,eax
0040396A jmp wmain+1Eh (40396Eh)
0040396C xor esi,esi
283: object->first();
0040396E mov eax,dword ptr [esi]
00403970 mov edx,dword …Run Code Online (Sandbox Code Playgroud) rtti ×10
c++ ×6
delphi ×4
abi ×1
casting ×1
delphi-xe ×1
design-time ×1
oop ×1
polymorphism ×1
runtime ×1
templates ×1
typeid ×1
types ×1
visual-c++ ×1