[英]Difference between bcc32 and bcc32c object lifetime
我有一个使用C ++ Builder 10.1 Berlin构建的跨平台C ++应用程序,在理解对象的生命周期处理方面遇到了问题,在这种情况下,在类外部声明了字符串。 我创建了一个新的表单应用程序并添加了一些代码。 cpp文件如下所示:
#include
#pragma hdrstop
#include "FmrMain.h"
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
const String Hello = "Hello";
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ShowMessage(Hello);
}
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
ShowMessage(Hello);
}
我使用CLANG增强的C ++ 11编译器bcc32c进行编译,运行应用程序并再次关闭表单。 调用TForm1 :: FormDestroy时,Hello已被销毁。 当我使用经典的编译器bcc32编译win32的代码时,在FormDestroy之后会销毁该字符串。
有人可以解释一下还是提供一些有关我必须寻找的主题的信息? 为什么基于CLANG的编译器在这里表现不同?
编辑
当我使用自定义类而不是字符串时,调试起来会更容易。
class Foo {
public:
Foo(){};
~Foo(){}
};
Foo A;
//--------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
}
创造和破坏的可能性就是这样。 我已经添加了调用堆栈。
bcc32c(CLANG C ++ 11编译器)
创建Foo
:004052C0 Foo(this =:00400000)
:00405070 __cxx_global_var_init3()
:004052A3 _GLOBAL__I_a()
:00405ab7; 〜富
:321fa2b7; C:\\ Program Files(x86)\\ Embarcadero \\ Studio \\ 18.0 \\ bin \\ CC32C240MT.DLL
:321fa6ff CC32C240MT .__ wstartup + 0xbb
创建Form1
:004052EC TForm1(this =:00402422,__ctor_flag ='\\ 0')
:0085c139 fmx240。@ Fmx @ Forms @ TApplication @ CreateForm $ qqrxp17System @ TMetaClasspv + 0x5d
:0085c349 fmx240。@ Fmx @ Forms @ TApplication @ RealCreateForms $ qqrv + 0x81
销毁
:004052D0〜Foo(this =:0040B7DC)
:0040509E __dtor_A()
:321f6246 CC32C240MT .___ call_atexit_procs + 0x52
:321f671c CC32C240MT .___退出+ 0x20
销毁Form1
:00405868〜TForm1(this =:5016E698)
bcc32(经典borland编译器)
创建Foo
:00404950 Foo :: Foo(this =:00409B74)
:004048A0 STCON0 ()
:00405727; IRoot
:322190f1; C:\\ Program Files(x86)\\ Embarcadero \\ Studio \\ 18.0 \\ bin \\ CC32240MT.DLL>:322193b5 CC32240MT .__ wstartup + 0xa5
创建Form1
:00404994 TForm1 :: TForm1(this =:02F2AE20,Owner =:02F39620)
:0095c139 fmx240。@ Fmx @ Forms @ TApplication @ CreateForm $ qqrxp17System @ TMetaClasspv + 0x5d
:0095c349 fmx240。@ Fmx @ Forms @ TApplication @ RealCreateForms $ qqrv + 0x81
销毁Form1
:00404ABC TForm1 ::〜TForm1(this =:02F2AE20)
销毁
:00404978 Foo ::〜Foo(this =:00409B74)
:0040493F STDES0 ()
:0040573f; IRoot>
:3221910f; C:\\ Program Files(x86)\\ Embarcadero \\ Studio \\ 18.0 \\ bin \\ CC32240MT.DLL
:3221915b; C:\\ Program Files(x86)\\ Embarcadero \\ Studio \\ 18.0 \\ bin \\ CC32240MT.DLL>:3221944a; C:\\ Program Files(x86)\\ Embarcadero \\ Studio \\ 18.0 \\ bin \\ CC32240MT.DLL
自动创建的TForm
对象由全局TApplication
对象拥有。 在应用程序的main()
/ wmain()
/ WinMain()
入口点函数退出后 ,该对象将被销毁(从而销毁其拥有的Forms)。 全局变量在应用程序清理期间被破坏。
在任何一个编译器中,不能保证全局String
的生存期超过全局TApplication
对象的生存期。 您依赖于未定义的行为 ,该行为基于不同单元之间全局变量的清除顺序。 更糟糕的是,您依赖于不同框架之间的清理顺序! 您的String
在您自己的C ++代码中,但是TApplication
对象在基于Delphi的RTL库中。
如果您的String
需要在使用它的TForm
的生命周期内保持活动状态, TForm
将其声明为该类的static
成员:
FmrMain.h:
//---------------------------------------------------------------------------
#ifndef FmrMainH
#define FmrMainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
static const String Hello;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
FmrMain.cpp:
//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include "FmrMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
const String TForm1::Hello = "Hello";
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ShowMessage(Hello);
}
void __fastcall TForm1::~TForm1()
{
ShowMessage(Hello);
}
//---------------------------------------------------------------------------
另外,使用wchar_t*
代替String
,则不会遇到任何清理问题:
//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include "FmrMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
static const wchar_t* Hello = L"Hello";
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ShowMessage(Hello);
}
void __fastcall TForm1::~TForm1()
{
ShowMessage(Hello);
}
//---------------------------------------------------------------------------
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.