我有一个各种类的实例列表.我需要能够在不知道要创建什么的情况下创建类的新实例.所涉及的所有对象都具有相同的祖先.实际复制对象的成员变量很容易......这是我遇到问题的新对象的创建.
不可否认我可以这样做:
case MyObjectTypeInstance.MyTypeEnum of
obj1:
Result:=TObjectType1.Create;
obj2:
Result:=TObjectType2.Create;
obj3:
Result:=TObjectType3.Create;
end;
Run Code Online (Sandbox Code Playgroud)
这不符合"开放/封闭原则".
最初我以为我可以做一些像"结果:= MyObjectTypeInstance.Create;" 但由于破坏者的困难,这并不像希望的那样有效.
这是最新的猜测我应该怎么做...
var
fooA, fooB:TFoo;
begin
fooA:=TFoo2.Create; // it could be any of many types
fooB:=? // how to create fooB of same class type as fooA????
// do something
fooA.Free;
fooB.Free;
end;
Run Code Online (Sandbox Code Playgroud)
我会以为这会更容易!
谢谢您的帮助!
我想从我的班级计算所有派生的实例,我试图这样做:
.h文件:
#ifndef _Parant
#define _Parant
#include<map>
class Parant
{
public:
Parant();
virtual ~Parant();
static void PrintInstances();
private:
static void AddInstance(const char* typeName);
static std::map<const char*, int> InstanceCounter;
};
#endif
Run Code Online (Sandbox Code Playgroud)
.cpp文件:
#include "Parant.h"
#include <typeinfo>
#include <iostream>
using namespace std;
Parant::Parant()
{
AddInstance(typeid(this).raw_name());
}
Parant::~Parant()
{
}
std::map<const char*, int> Parant::InstanceCounter;
void Parant::AddInstance(const char* typeName)
{
InstanceCounter[typeName]++;
}
void Parant::PrintInstances()
{
for(map<const char*,int>::iterator i = InstanceCounter.begin(); i != InstanceCounter.end(); i++)
{
cout << " typename: " << i -> first …Run Code Online (Sandbox Code Playgroud) 我正在使用 Delphi 应用程序。我创建了一个如下所示的表单:

我想通过代码从这个控件中制作组件。但是不能通过组件-->创建组件模板-->等等。
如何通过delphi代码使组件模板脱离表单控制。??提前谢谢。
在我的IsSame函数中,true如果两个指针都指向同一类型的对象,我想返回.所以只有中间调用应该返回true.D1并且B不应该被认为是相同的.
以下似乎正是我想要的但是根据标准安全吗?
#include <stdio.h>
class B { virtual void foo() {} };
class D1 : public B { };
class D2 : public B { };
class D3 : public B { };
bool IsSame(B*a, B*b) {
if (a == 0 || b == 0)
return false;
return *(intptr_t*)a == *(intptr_t*)b;
}
int main() {
D1 d1;
D2 d2;
D1 d1b;
B b;
printf("%d %d %d\n", IsSame(&d1, &d2), …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个spec实用程序库.
规范之一是TExpressionSpecification.基本上,它通过评估内部TExpression来实现规范模式.
其中一个TExpression是TPropertyExpression.它只是一个表达式,通过Rtti的名称获取属性的值.
我以最简单的方式实现它,但实在无法理解为什么它会向我抛出AV.
我悄悄地调试了调试器.所有类型都是它们应该是的.我只是不知道为什么TRttiProperty.GetValue破坏了破坏.
有人可以帮忙吗?单位规格;
interface
uses
Classes;
type
TPropertyExpression<TObjectType, TResultType> = class
private
FPropertyName: string;
public
constructor Create(aPropertyName: string); reintroduce;
function Evaluate(aObject: TObjectType): TResultType;
property PropertyName: string read FPropertyName write FPropertyName;
end;
procedure TestIt;
implementation
uses
Rtti;
constructor TPropertyExpression<TObjectType, TResultType>.Create(aPropertyName:
string);
begin
inherited Create;
PropertyName := aPropertyName;
end;
function TPropertyExpression<TObjectType, TResultType>.Evaluate(aObject:
TObjectType): TResultType;
var
aCtx : TRttiContext;
aModelType : TRttiType;
aResultType : TRttiType;
aProperty : TRttiProperty;
aValue : TValue;
begin
aCtx := TRttiContext.Create;
aModelType := aCtx.GetType(System.TypeInfo(TObjectType));
aResultType := …Run Code Online (Sandbox Code Playgroud) 我无法根据名称而不是序数值获取枚举类型。我需要在类属性的 RTTI 循环内执行此操作。我尝试过使用 GetEnumName 和 TRTTIEnumerationType.GetName,但我似乎无法从 TRTTIProperty 实例将这些东西组合在一起。
请帮助?(下面的框架代码示例)
用途
RTTI、类型信息;
类型
TCustomColor = (ccBlack, ccBrown, ccBlue);
TMyClass = 类
民众
属性自定义颜色:TCustomColor;
结尾;
程序输出;
变量
rc:TRTTIContext;
rt : TRTTI 类型;
rp : TRTTI 属性;
mc : TMyClass;
开始
mc.CustomColor := ccBlue;
rt := rc.GetType(mc.ClassType);
对于 rt.GetProperties 中的 rp 做
如果 rp.PropertyType.TypeKind = tkEnumeration 那么
开始
// TODO: 从属性中检索“ccBlue”
结尾;
结尾;
程序输入;
变量
n、s:字符串;
o:T 对象;
rc:TRTTIContext;
rt : TRTTI 类型;
开始
n := '自定义颜色';
s := 'ccBlue';
// 注意:o 是从它的类类型的字符串实例化的 … 我用SourceProperties[0].SetValue(lObject, lStream)设置MemoryStream : TMemoryStream的属性lObject。
如果我随后释放了lStream, 的MemoryStream属性lObject似乎被设置为nil。
如果我不释放lStream,就会出现内存泄漏。
通过 RTTI将 分配lStream给MemoryStream属性的正确方法是什么?
下面列出了完整的示例代码:
unit Unit28;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
FMX.Controls.Presentation, FMX.StdCtrls, System.Rtti;
type
TMyObject = Class(TObject)
private
pMemoryStream : TMemoryStream;
published
property MemoryStream : TMemoryStream read pMemoryStream write pMemoryStream;
constructor Create;
destructor Destroy;override;
end;
type
TForm28 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject); …Run Code Online (Sandbox Code Playgroud) 如果我有一个超类,比如说Animal,
和两个子类:Zebra和Giraffe,
如果我决定定义一个动物矢量:
Vector <Animal> animals = new Vector();
Run Code Online (Sandbox Code Playgroud)
我想说:你可以添加长颈鹿,但你必须先拥有至少一个斑马.
不使用RTTI的最佳方法是什么?(instanceof)
我有一些newObject具有未知属性的对象,我希望能够在不知道属性类型的情况下为其属性赋值.
到目前为止我能做的最好的是
vCtx := TRttiContext.Create;
vType := vCtx.GetType(newObject.ClassType);
for vProp in vType.GetProperties do
begin
vPropValue := 'Test Value';
val := TValue.From<String>( vPropValue);
vProp.SetValue( newObject , val );
end;
Run Code Online (Sandbox Code Playgroud)
当然,这假设属性是类型 string
我如何使这更一般?
我正在使用Delphi 10.2 Tokyo,并且遇到以下情况:
假设我具有以下过程,以验证对象的属性:
procedure TGenericUnit.VerifyProps<T>(_AObj: T);
var
AContext: TRttiContext;
AType: TRttiType;
AProp: TRttiProperty;
begin
AType := AContext.GetType(T);
for AProp in AType.GetProperties do
if AProp.PropertyType is TObject then
// VerifyProps<?>(?);
end;
Run Code Online (Sandbox Code Playgroud)
如果我不知道它将是哪种类型的对象,并且不一定与T相同,该如何递归调用此过程?