小编kdt*_*top的帖子

隐藏基类的虚方法有什么问题?

我一直在收到关于Delphi编译器的警告 Method 'Create' hides virtual method of base.

我已经回顾了几个Stack Overflow链接(见下文),我不明白这个警告背后的逻辑,以及为什么它被认为是错误的编码实践.我希望别人能帮助我理解

我将包含一些示例代码:

type    
  TMachine = class(TPersistent)
  private
  public
    Horsepower : integer;
    procedure Assign(Source : TMachine);
  end;

...

procedure TMachine.Assign(Source : TMachine);
begin
  inherited Assign(Source);
  Self.Horsepower := Source.HorsePower;
end;
Run Code Online (Sandbox Code Playgroud)

这会导致编译器警告.

[dcc32 Warning] Unit1.pas(21): W1010 Method 'Assign' hides virtual method of base type 'TPersistent'
Run Code Online (Sandbox Code Playgroud)

我一直忽视这个警告,因为它对我没有任何意义.但这让我以另一种方式遇到了麻烦(请参阅我在这里的另一篇文章:为什么Delphi在动态对象创建过程中会调用错误的构造函数?)所以我决定尝试更好地理解这一点.

我知道如果我使用保留字reintroduce,错误就会消失,但我已经看到它反复发布这是一个坏主意.正如Warren P在这里所写的那样(德尔福:方法'创造'隐藏基础的虚拟方法 - 但它就在那里),"恕我直言,如果你需要重新引入,你的代码闻起来很可怕".

我想我理解"隐藏"是什么意思.正如David Heffernan在这里所说的那样(导致"W1010方法'%s'隐藏基类型'%s'的虚拟方法"的原因是什么?):

隐藏的含义是,从派生类中,您不再能够访问基类中声明的虚方法.您不能引用它,因为它与派生类中声明的方法具有相同的名称.后一种方法是从派生类中可见的方法.

但我有点困惑,因为似乎祖先方法并没有真正隐藏,因为派生类总是只能使用inherited关键字来调用基类中的方法.所以'隐藏'真的意味着'有些隐藏'吗?

我想我也明白使用保留字override会阻止编译器警告,但程序签名必须相同(即没有新添加的参数).我不能在这里使用它.

我不明白为什么隐藏是值得警告的.在我上面的代码示例中,我不希望用户TMachine.Assign()以某种方式使用TPersistent.Assign().在我的扩展课程中,我扩展了需求,因此希望他们使用新的和改进的功能.因此,隐藏旧代码似乎正是我想要的.我对 …

delphi oop polymorphism inheritance

8
推荐指数
1
解决办法
916
查看次数

ThreeJS:调整浏览器窗口大小后计算透视相机的 FOV

我需要在浏览器窗口大小更改后获取正确的 Three.JS 相机 FOV。我已查看以下问题,但似乎无法找到我的问题的答案:

我的相机设置如下(“this”指我设置的 gameCamera 对象):

const CAMERA_DIST = 8000;   

-other stuff- 

this.camera = new THREE.PerspectiveCamera(
  45,                                      //FOV parameter
  window.innerWidth / window.innerHeight,  //aspect ratio parameter
  1,                                       //frustum near plane parameter
  CAMERA_DIST                              //frustum far plane parameter
);
Run Code Online (Sandbox Code Playgroud)

当用户调整浏览器窗口大小时,将调用以下更新代码。我包含了在这里找到的代码:(如何用三个 js 计算透视相机的 fov?)用于尝试计算新的 FOV('aFOV')。

function onWindowResize() {
  gameCamera.camera.aspect = window.innerWidth / window.innerHeight;
  console.log(gameCamera.camera.fov);
  gameCamera.camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
  console.log(gameCamera.camera.fov);
  let aFOV = 2*Math.atan((window.innerHeight)/(2*CAMERA_DIST)) * (180/Pi);
  console.log(aFOV);
  windowHalfX = window.innerWidth / 2;
  windowHalfY = window.innerHeight / 2;
} …
Run Code Online (Sandbox Code Playgroud)

javascript 3d perspectivecamera three.js

6
推荐指数
1
解决办法
5475
查看次数

Angularjs日期输入允许空输入

Angularjs相对较新

我在这里阅读了日期输入文档: Angularjs Date Input 它声明模型(输入绑定的数据)必须是JavaScript日期对象.

但是,在我的应用程序中,我希望能够显示最初为空的日期输入字段(除了占位符提示之外).如果用户选择不输入日期,则这是可接受的情况.

我的理解是JavaScript日期对象总是描述一些日期.所以日期输入,因为它绑定到模型,将始终显示一些日期.如果用户忽略或跳过日期输入,则似乎仍然提供了日期.我不希望这种情况发生.

我想到的唯一解决方案是使用可以为空或包含日期的文本编辑字段.然后我必须以某种方式解析用户输入.但它没有一个不错的日期选择器.

有关如何解决此问题的任何建议?

string date datepicker angularjs

4
推荐指数
1
解决办法
9319
查看次数

这个Delphi线程代码是否正确?

我知道很多线程都讨论过Delphi线程.我试过检查它们,但没有找到我的问题的答案.

背景: 我发现在浏览器加载Adobe Acrobat Reader DC后,释放TWebBrowser可能需要10秒以上.我想不知何故它正在检查更新或其他什么.尝试使用浏览器关闭表单时很烦人.

我想也许我可以让后台线程释放浏览器.所以我将浏览器变量移动到一个全局变量(私有存储在单元的实现部分).一次只能使用其中一种形式.然后我尝试让一个线程在后台释放它.它没有像我预期的那样工作.

示例代码

interface
  TMyform = class(TForm)
    pnlBowserHolder: TPanel;
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    //WebBrowser : TWebBrowser;  <-- moved to global variable
  public
    { Public declarations }
  end;

implementation

type
  TBackgroundBrowserKillerThread = class(TThread)
  public
    procedure Execute; override;
  end;

var
  WebBrowser : TWebBrowser;
  BrowserKillerThread : TBackgroundBrowserKillerThread;

procedure TfrmLabImageViewer.FormCreate(Sender: TObject);
begin
  WebBrowser := TWebBrowser.Create(Self);
  TWinControl(WebBrowser).Parent := pnlBowserHolder;
  WebBrowser.Align := alClient;
end;

procedure TfrmLabImageViewer.FormDestroy(Sender: TObject);

begin
  BrowserKillerThread := TBackgroundBrowserKillerThread.Create(true);
  Application.ProcessMessages;
  BrowserKillerThread.Execute();  
  //WebBrowser.Free;
end;

procedure TBackgroundBrowserKillerThread.Execute();
begin …
Run Code Online (Sandbox Code Playgroud)

delphi acrobat multithreading twebbrowser

1
推荐指数
1
解决办法
837
查看次数

有没有办法在Delphi中通过类信息参数动态类型转换?

当使用作为传递参数的类时,我在理解类型转换方面遇到了一些困难。我尝试寻找这个但找不到其他答案。

我正在使用一些旧的 Delphi 代码,使用 Delphi 2006,它不支持泛型(在 Delphi 2009 中引入)。

该代码使用 TList 来存储指向特定类型的实例化类的指针。当清除列表时,他们使用这个:

  procedure ClearList(AList: TList);  
  var i: Integer;
  begin
    for i := 0 to AList.Count - 1 do
      TObject(AList[i]).Free;
    AList.Clear;
  end; 
Run Code Online (Sandbox Code Playgroud)

它的名字是这样的:

  ClearList(FExtraVisitTypes);
  ClearList(FDiagnoses);
  ClearList(FProcedures);
  ClearList(FImmunizations);
  ClearList(FSkinTests);
  ClearList(FPatientEds);
  ClearList(FHealthFactors);
  ClearList(FExams);
Run Code Online (Sandbox Code Playgroud)

我对此的理解可能有所偏差,但我担心如果将指向的对象作为 TObject 释放,则不会调用后代对象的析构函数,从而可能导致内存泄漏。(我的多态功夫有点生疏,可能会造成我的困惑。)

所以我尝试将清除功能更改如下:

 procedure ClearList(AList: TList; ItemClass: TPCEItemClass);  //mod to add ItemClass
  var i: Integer;
  begin
    for i := 0 to AList.Count - 1 do begin
      (AList[i] as ItemClass).Free;
    end;
    AList.Clear;
  end;
Run Code Online (Sandbox Code Playgroud)

TPCEItemClass 定义如下:

  TPCEItemClass = class of TPCEItem; …
Run Code Online (Sandbox Code Playgroud)

delphi polymorphism typecast-operator typecasting-operator

0
推荐指数
1
解决办法
122
查看次数