25

看看这个类:

TTest = class(TObject)  
public  
  constructor Create(A:Integer);overload;  
  constructor Create(A,B:Integer);overload;  
end;

现在,当我们要使用该类时:

var  
  test:  TTest;  
begin  
  test:= TTest.Create; //this constructor is still visible and usable!  
end;

谁能帮我隐藏这个构造函数?

4

4 回答 4

23

只要您重载了名为 的构造函数Create,就不能TObject在派生自 时隐藏无参数构造函数TObject

这在这里讨论:http ://www.yanniel.info/2011/08/hide-tobject-create-constructor-delphi.html

如果您准备在您的课程之间放置另一个课程,TObject您可以使用Andy Hausladen 的技巧

TNoParameterlessContructorObject = class(TObject)
strict private
  constructor Create;
end;

TTest = class(TNoParameterlessContructorObject)
public
  constructor Create(A:Integer);overload;  
  constructor Create(A,B:Integer);overload;  
end;
于 2012-12-22T13:27:20.447 回答
12

你可以通过引入一个非重载的 Create 来隐藏继承的 Create。由于您需要两个重载的 Create,您可以使用可选的第二个参数将它们合并到一个 Create 中:

TTest = class(TObject)  
public  
  constructor Create(A:Integer; B: Integer = 0); 
end;

这将给出编译器警告,表明您正在隐藏默认的无参数构造函数。要摆脱警告,您可以像这样声明隐藏构造函数:

TTest = class(TObject)  
public  
  constructor Create(A:Integer; B: Integer = 0); reintroduce;
end;

或者,如果这不可行,您可以引入一个中间类,引入第一个创建,然后是具有重载的第二个的最终类:

preTest = class(TObject)  
public  
  constructor Create(A:Integer); reintroduce;
end;

TTest = class(preTest)  
public  
  constructor Create(A,B:Integer);overload;  
end;
于 2012-12-22T13:25:33.237 回答
2

另一种选择是在运行时使用deprecated关键字和raise异常。

TTest = class(TObject)  
public  
  constructor Create; overload; deprecated 'Parameterless constructor is not Supported for a TTest class';
  constructor Create(const A: Integer); overload;  
  constructor Create(const A, B: Integer); overload;  
end;

implementation

constructor TTest.Create;
begin
  raise Exception.Create('Parameterless constructor is not Supported for a TTest class.');
end;
于 2020-02-11T20:43:14.610 回答
1

通过两次继承,可以防止用户在设计时而不是运行时创建 TMySingleton 类。

unit MySingleton;

interface

uses System.Classes, System.SysUtils;

type
  // Constructor Block external access
  THideConstructor = class abstract
  strict protected
    constructor Create; virtual; abstract;
  end;

  // Switching the access to the Create function THideConstructor in TObject through the constructor Overloading
  // Declaring Create Method as a procedure to prevent class call-TMySingle.Create('string') call impossible
  TOverloadConstructor = class(THideConstructor)
  public
    procedure Create(s: string); reintroduce; overload; deprecated 'null method';
  end;

  TMySingleton = class sealed(TOverloadConstructor)
  private
    class var MyObj: TMySingleton;
  strict protected
    // Hiding TOverloadConstructor.Create(s: string);
    // Implement THideConstructor.Create
    constructor Create; override;
  public
    class function Obj: TMySingleton;
    function Echo(const value: string): String;

    destructor Destroy; override;
  end;

implementation

{ TMySingleton }

constructor TMySingleton.Create;
begin
  // TODO
end;

destructor TMySingleton.Destroy;
begin
   Self.MyObj := nil;
   inherited;
end;

function TMySingleton.Echo(const value: string): String;
begin
  result := value;
end;

class function TMySingleton.Obj: TMySingleton;
begin
  if MyObj = nil then
    MyObj := Self.Create;
  result := MyObj;
end;

{ TOverloadContructor }

procedure TOverloadConstructor.Create(s: string);
begin
  // null method
end;

initialization

TMySingleton.MyObj := nil;

finalization

if Assigned(TMySingleton.MyObj) then
  FreeAndNil(TMySingleton.MyObj);

end.

如果用户

var
  Singleton: TMySingleton;
begin
  Singleton := TMySingleton.Create;

发生设计时错误。

[dcc32 Error] Unit1.pas(33): E2625 Private member 'THideConstructor.Create' is inaccessible here MySingleton.pas(11): Related method: constructor Create;

在此处输入图像描述

此外,您看不到任何名为Create的自动完成提示。

于 2020-11-12T06:49:33.280 回答