Board logo

Subject: BCB下面virtual不正常? [Print This Page]

Author: jAmEs_    Time: 2007-2-9 11:42     Subject: BCB下面virtual不正常?

//头文件
//---------------------------------------------------------------------------

#ifndef uAutoFireH
#define uAutoFireH
//---------------------------------------------------------------------------
class PACKAGE TAutoFire{
protected:
  virtual void __fastcall Constructor(void);
  virtual void __fastcall Destructor(void);
public:
  TAutoFire();
  virtual ~TAutoFire();
};

class PACKAGE TPerformanceLogger : public TAutoFire{
private:
  TFileStream *m_pFileStream;
protected:
  virtual void __fastcall Constructor(void);
  virtual void __fastcall Destructor(void);
public:
  TPerformanceLogger(const AnsiString FileName = "c:\\PerformanceLogger.log");
  virtual ~TPerformanceLogger();
};

#endif
//实现
//---------------------------------------------------------------------------


#include <vcl.h>
#pragma hdrstop

#include "uAutoFire.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

TAutoFire::TAutoFire()
{
  Constructor();
}

TAutoFire::~TAutoFire()
{
  Destructor();
}

void __fastcall TAutoFire::Constructor(void)
{
}

void __fastcall TAutoFire:estructor()
{
}

TPerformanceLogger::TPerformanceLogger(const AnsiString FileName)
{
  m_pFileStream = new TFileStream(FileName, fmCreate|fmOpenReadWrite);
  TAutoFire::TAutoFire();
}

TPerformanceLogger::~TPerformanceLogger()
{
  delete m_pFileStream;
}

void __fastcall TPerformanceLogger::Constructor()
{
  m_pFileStream->Seek(0, soFromEnd);
  AnsiString sTemp = AnsiString().sprintf("%s - Begin.\r\n", FormatDateTime("yyyy-MM-dd hh:nn:ss.zzz", Now()));
  m_pFileStream->Write(sTemp.c_str(), sTemp.Length());
}

void __fastcall TPerformanceLogger:estructor()
{
  AnsiString sTemp = AnsiString().sprintf("%s - End.\r\n", FormatDateTime("yyyy-MM-dd hh:nn:ss.zzz", Now()));
  m_pFileStream->Write(sTemp.c_str(), sTemp.Length());
}

上面的virtual使用上有问题吗?为什么不会调用TPerformanceLogger的Constructor和Destructor?
Author: jAmEs_    Time: 2007-2-9 11:44

之前曾经试过这个问题,没有解决,都不知道错在哪里,看来C++还不是精通。不知道哪位知道问题所在?
Author: jAmEs_    Time: 2007-2-9 14:52

难道是C++构造函数和释构函数下面调用virtual是不会调用子类的?
我试过Delphi是可以的。
Author: kendling    Time: 2007-2-9 15:08

哈,这个不大清楚,很久没玩BCB了。
Author: Passion    Time: 2007-2-9 15:47

Delphi 的也得写上inherited才会调吧?
Author: jAmEs_    Time: 2007-2-10 09:33

Delphi
TTest = class
protected
  procedure constuctor; virtual;
public
  constructor create;
end;

TTest1 = class(TTest)
protected
  procedure constuctor; override;
end;

...

procedure TTest.constructor;
begin
  ShowMessage('TTest.constructor');
end;

constructor TTest.create;
begin
  constructor;
end;

procedure TTest1.constructor;
begin
  ShowMessage('TTest1.constructor');
end;

...
var
  test: TTest;
begin
  test := TTest1.Create; // 它调用TTest1.constructor的,如果在C++将调用TTest.constructor
  test.Free;
end;

我只想说明,对于虚函数,在构造和释构调用它时,C++和Pas处理好像不一样,C++只会调用定义虚函数基类的实现,但是Pas调用的是构造实例类的那个。也许是它们的区别,不过没有一个明确说法,网上找不到。
不知道哪位高人知道是否这样?
Author: Passion    Time: 2007-2-10 10:16

Delphi 的没显式写明 virtual 的就没这个多态性吧,而C++默认就有的。
Author: jAmEs_    Time: 2007-2-11 11:01

说实在,没有认真理解过多态,不过好像与我这个没有什么关系吧?
我只想说明,virtual在Pas和C++下面,如果调用的是构造和释构,它们的调用存在差异,不知道是不是这样而已。。。而我自己也不是很清楚标准是不是这样,所以提出来讨论。。。
Author: Passion    Time: 2007-2-11 12:26

它调用TTest1.constructor的,——这个没错。

如果在C++将调用TTest.constructor——贴出C++代码看看?
Author: jAmEs_    Time: 2007-2-11 19:16

C++代码就在楼顶啊。
其实我在BCB和VC++都测试过,结果都是调用TTest.constructor,只是还是想确认清楚究竟是不是这样。
Author: Passion    Time: 2007-2-11 21:33

我没看连贯,不好意思。
Author: crystal999    Time: 2007-2-14 15:54

TAutoFire::函数名
必须这样调用父类的就象delphi里面inherited
多态不是在这个地方体现的
Author: Passion    Time: 2007-2-14 23:52

他写了TAutoFire::函数名吧。




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0