Delphi中的OleVariant是按值复制还是按引用复制?

Delphi中的OleVariant是按值复制还是按引用复制?,delphi,Delphi,我有这样一个代码: function Test: OleVariant; var r: OleVariant; begin r := VarArrayCreate([0, 100], varVariant); // some other code goes here Result := r; // does this perform deep or shadow copy? end; 所以问题是,对于OleVariant类型,赋值操作复制值或引用 它是否取决于类型 像这

我有这样一个代码:

function Test: OleVariant;
var
   r: OleVariant;
begin
   r := VarArrayCreate([0, 100], varVariant);
   // some other code goes here
   Result := r; // does this perform deep or shadow copy?
end;
所以问题是,对于OleVariant类型,赋值操作复制值或引用


它是否取决于类型

像这样的简单测试

function Test: OleVariant;
var
   r: OleVariant;
begin
   r := VarArrayCreate([0, 100], varVariant);
   // some other code goes here
   r[1] := 'Deep';
   Result := r; // does this perform deep or shadow copy?
   r[1] := 'Shallow'
end;

procedure TForm10.Button2Click(Sender: TObject);
begin
  ShowMessage(Test[1]);
end;
给出了深刻的答案


评论中有一些猜测,测试用例可能是错误的,因为赋值
r[1]:=“Deep”触发了一些写时复制功能。我可以确认variant的variant数组的赋值(即使有未赋值的元素)是作为深度副本完成的,这里没有cow。

OleVariant
是Win32 OLE结构的包装器。
VARIANT
数据的赋值始终是深度的,因为
VARIANT
除了接口之外,没有任何参考计数数据的概念(在这种情况下,赋值会增加参考计数)。
VARIANT
中的数组是使用结构实现的,该结构没有引用计数,因此必须进行深度复制(如果数组持有接口指针,则它们的引用计数会增加)


顺便说一句,
VarArrayCreate()
返回一个Delphi
变量,而不是
OleVariant
。将
Variant
分配给
OleVariant
会将数据转换为Win32
Variant
结构支持的OLE兼容格式,包括对数组使用
SAFEARRAY

是否尝试过
var pOleVariant:^OleVariant视情况而定。您是只想知道此变体的答案,还是想了解所有不同类型的答案?是的,我想知道不同类型的答案。:)您需要在问题中明确这些内容。它实际上没有给出答案:数组有可能实现为写时拷贝,其中
Result:=r
将执行浅拷贝,但分配给
r[1]
将强制执行深拷贝。(我不认为这种情况真的发生在variant数组中,但它确实发生在Delphi的其他一些具有特殊语言支持的类型中,因此您需要排除这种情况。)@hvd我可以向您保证,variant数组的variant赋值(即使有未赋值的元素)是通过深度复制完成的,这里没有cow。我已经非常确定,我的意思是,你的回答在我看来不够充分。@hvd:这真的重要吗?结果是一样的。@RudyVelthuis是的,这很重要。如果这个逻辑在这里没有争议,那么如果其他一些问题询问使用COW的数组的不同实现,那么想要回答的人可能会被这个人的错误推理误导,发布一个事实上不正确的答案。但由于编辑引起了人们对潜在问题的关注,我认为现在可以了。