例如:
public class Person
{
public Person()
{
}
~Person()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我什么时候应该手动创建析构函数?什么时候需要创建析构函数?
不久前我问了一个关于隐式接口变量的类似问题.
这个问题的来源是我的代码中的一个错误,因为我没有意识到编译器创建的隐式接口变量的存在.拥有它的过程完成后,该变量已完成.这反过来导致了由于变量的生命周期比我预期的更长的错误.
现在,我有一个简单的项目来说明编译器的一些有趣的行为:
program ImplicitInterfaceLocals;
{$APPTYPE CONSOLE}
uses
Classes;
function Create: IInterface;
begin
Result := TInterfacedObject.Create;
end;
procedure StoreToLocal;
var
I: IInterface;
begin
I := Create;
end;
procedure StoreViaPointerToLocal;
var
I: IInterface;
P: ^IInterface;
begin
P := @I;
P^ := Create;
end;
begin
StoreToLocal;
StoreViaPointerToLocal;
end.
Run Code Online (Sandbox Code Playgroud)
StoreToLocal编译就像你想象的那样.局部变量I(函数的结果)作为隐式var参数传递给Create.通过StoreToLocal一次通话即可获得整齐的结果IntfClear.没有惊喜.
但是,StoreViaPointerToLocal对待方式不同.编译器创建一个传递给它的隐式局部变量Create.当Create返回时,对分配P^进行.这使例程中有两个局部变量保存对接口的引用.StoreViaPointerToLocal两次调用结果的整理结果IntfClear.
编译后的代码StoreViaPointerToLocal是这样的:
ImplicitInterfaceLocals.dpr.24: begin
00435C50 55 …Run Code Online (Sandbox Code Playgroud) 我想知道为什么这是有效的:
set(range(10)) - set(range(5))
Run Code Online (Sandbox Code Playgroud)
但这不是有效的:
set(range(10)) + set(range(5))
Run Code Online (Sandbox Code Playgroud)
是因为'+'可能意味着交叉和联合吗?
考虑这个程序:
#include <stdio.h>
int main(void)
{
unsigned int a;
printf("%u %u\n", a^a, a-a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是不确定的行为?
从表面上看,它a是一个未初始化的变量.所以这指向未定义的行为.但是a^a并且a-a等于0所有的价值a,至少我认为是这样的.有可能有某种方式来证明行为是明确定义的吗?
更新: XE2 Update 2修复了下面描述的错误.
下面的程序,从真实程序中减少,在XE2中失败.这是从2010年开始的回归.我没有XE可以测试,但我希望程序在XE上运行正常(感谢Primož确认代码在XE上正常运行).
program COMbug;
{$APPTYPE CONSOLE}
uses
SysUtils, Variants, Windows, Excel2000;
var
Excel: TExcelApplication;
Book: ExcelWorkbook;
Sheet: ExcelWorksheet;
UsedRange: ExcelRange;
Row, Col: Integer;
v: Variant;
begin
Excel := TExcelApplication.Create(nil);
try
Excel.Visible[LOCALE_USER_DEFAULT] := True;
Book := Excel.Workbooks.Add(EmptyParam, LOCALE_USER_DEFAULT) as ExcelWorkbook;
Sheet := Book.Worksheets.Add(EmptyParam, EmptyParam, 1, EmptyParam, LOCALE_USER_DEFAULT) as ExcelWorksheet;
Sheet.Cells.Item[1,1].Value := 1.0;
Sheet.Cells.Item[2,2].Value := 1.0;
UsedRange := Sheet.UsedRange[LOCALE_USER_DEFAULT] as ExcelRange;
for Row := 1 to UsedRange.Rows.Count do begin
for Col := 1 to UsedRange.Columns.Count do begin
v := …Run Code Online (Sandbox Code Playgroud) 我不止一次建议人们使用类型的返回值WideString进行互操作.
这个想法是a WideString和a一样BSTR.因为a BSTR是在共享COM堆上分配的,所以在一个模块中分配并在另一个模块中解除分配是没有问题的.这是因为所有各方都同意使用相同的堆,即COM堆.
但是,它似乎WideString不能用作互操作的函数返回值.
考虑以下Delphi DLL.
library WideStringTest;
uses
ActiveX;
function TestWideString: WideString; stdcall;
begin
Result := 'TestWideString';
end;
function TestBSTR: TBstr; stdcall;
begin
Result := SysAllocString('TestBSTR');
end;
procedure TestWideStringOutParam(out str: WideString); stdcall;
begin
str := 'TestWideStringOutParam';
end;
exports
TestWideString, TestBSTR, TestWideStringOutParam;
begin
end.
Run Code Online (Sandbox Code Playgroud)
和以下C++代码:
typedef BSTR (__stdcall *Func)();
typedef void (__stdcall *OutParam)(BSTR &pstr);
HMODULE lib = LoadLibrary(DLLNAME);
Func TestWideString = (Func) GetProcAddress(lib, "TestWideString"); …Run Code Online (Sandbox Code Playgroud) 例如:
char a[] = "abc\0";
Run Code Online (Sandbox Code Playgroud)
标准C是否说0必须附加另一个值的字节,即使字符串最后已经为零?那么,sizeof(a)等于4还是5?
我知道我可以调用GetVersionEx Win32 API函数来检索Windows版本.在大多数情况下,返回值反映了我的Windows版本,但有时并非如此.
如果用户在兼容层下运行我的应用程序,则GetVersionEx将不报告实际版本,而是报告兼容层强制执行的版本.例如,如果我正在运行Vista并在"Windows NT 4"兼容模式下执行我的程序,则GetVersionEx将不会返回版本6.0而是4.0.
有没有办法绕过这种行为并获得真正的Windows版本?
我正在查看arcsin通过计算实现的运行时库实现:
ArcTan(X, Sqrt(1 - X*X))
Run Code Online (Sandbox Code Playgroud)
但是,计算1 - X*X实际评估的代码(1-X)*(1+X).是否有理由选择后者?我怀疑后者X会将舍入不准确度降低到接近零,但我无法理解为什么会这样.