我希望其他对象中包含的对象不必分配内存。例如在Delphi中我可以这样写:
type
TTest = class
obj1: tobject1;
obj2: tobject2;
constructor Create;
destructor Destroy; override;
end;
constructor TTest.Create;
begin
inherited;
obj1 := tobject1.Create;
obj2 := tobject2.Create;
end;
destructor TTest.Destroy;
begin
obj1.Free;
obj2.Free;
inherited;
end;
类似的C ++代码如下所示:
class TTest {
tobject1 obj1;
tobject2 obj2;
};
我想关注的区别在于Delphi版本中有3个内存分配,而C ++版本只有1个。有没有办法只在Delphi中为一个完整的对象及其子对象分配一个内存,就像在C ++中一样?
更新:完整的C ++测试代码:
class tobject1 { public: int aaa; };
class tobject2 { public: int bbb; };
class TTest {
tobject1 obj1;
tobject2 obj2;
public:
void doThing() { obj1.aaa = obj2.bbb; };
};
int main()
{
{TTest * test = new TTest; test->doThing(); delete test; }
{TTest test; test.doThing(); }
return 0;
}
反汇编代码:
{TTest * test = new TTest; test->doThing(); delete test; }
013D182E push 8
013D1830 call operator new (013D1299h)
013D1835 add esp,4
013D1838 mov dword ptr [ebp-0E4h],eax
013D183E mov eax,dword ptr [ebp-0E4h]
013D1844 mov dword ptr [ebp-8],eax
013D1847 mov ecx,dword ptr [ebp-8]
013D184A call TTest::doThing (013D133Eh)
013D184F mov eax,dword ptr [ebp-8]
013D1852 mov dword ptr [ebp-0F0h],eax
013D1858 push 8
013D185A mov ecx,dword ptr [ebp-0F0h]
013D1860 push ecx
013D1861 call operator delete (013D104Bh)
013D1866 add esp,8
{TTest test; test.doThing(); }
013D1869 lea ecx,[ebp-18h]
013D186C call TTest::doThing (013D133Eh)
对于包含子对象的新对象,c ++对象只需要1个内存分配,如果将对象放在堆栈而不是堆上,则甚至需要0个内存分配。
更新:完整的Delphi测试代码:
program Project1;
type
tobject1 = class
aaa: longint;
end;
tobject2 = class
bbb: longint;
end;
TTest = class
obj1: tobject1;
obj2: tobject2;
constructor Create;
destructor Destroy; override;
procedure doThing;
end;
constructor TTest.Create;
begin
inherited;
obj1 := tobject1.Create;
obj2 := tobject2.Create;
end;
destructor TTest.Destroy;
begin
obj1.Free;
obj2.Free;
inherited;
end;
procedure TTest.doThing;
begin
obj1.aaa := obj2.bbb;
end;
var
test: TTest;
begin
test := TTest.Create;
test.doThing;
test.Free;
end.
反汇编的分配代码:
Project1.dpr.35: test := TTest.Create;
0040A0F4 B201 mov dl,$01
0040A0F6 A19C924000 mov eax,[$0040929c]
0040A0FB E8DCF2FFFF call TTest.Create
0040A100 A3F8F44000 mov [$0040f4f8],eax
Project1.dpr.36: test.doThing;
0040A105 A1F8F44000 mov eax,[$0040f4f8]
0040A10A E865F3FFFF call TTest.doThing
Project1.dpr.37: test.Free;
0040A10F A1F8F44000 mov eax,[$0040f4f8]
0040A114 E8DBA1FFFF call TObject.Free
反汇编的创建代码:
Project1.dpr.16: obj1 := tobject1.Create;
004093F4 B201 mov dl,$01
004093F6 A144914000 mov eax,[$00409144]
004093FB E8C4AEFFFF call TObject.Create
00409400 8B55FC mov edx,[ebp-$04]
00409403 894204 mov [edx+$04],eax
Project1.dpr.17: obj2 := tobject2.Create;
00409406 B201 mov dl,$01
00409408 A1F0914000 mov eax,[$004091f0]
0040940D E8B2AEFFFF call TObject.Create
00409412 8B55FC mov edx,[ebp-$04]
00409415 894208 mov [edx+$08],eax
此Delphi对象需要3个内存分配,用于包含2个子对象的新对象。是否可以使用对象而不是记录(因为它们不支持继承而完全不相同)来减少像C ++中的一个分配(如果放在堆栈中,甚至是0)(
)答案 0 :(得分:2)
在Delphi中,类是引用类型,因此在实例化时始终会产生堆位置。因此,您无法使用类实现所需的内存布局。
相比之下,记录是价值类型。如果将两个嵌入类型放入记录中,那么内存将按您的意愿布局,并且只有一个堆分配。
答案 1 :(得分:0)
不,如果不为该实例分配内存,则无法分配类的实例。 Delphi和C ++之间也没有区别。