C++ 为什么我的编译器不能按预期工作?
我在multiply在线编译器上尝试了这段代码,它运行得很好,但是当我在我的计算机上尝试它时,出现了一些问题(虽然不完全是错误,但它没有按预期工作) 对于静态对象和gloabl对象都不调用析构函数。若我把函数create放在main后面,那个么在它调用create中对象的构造函数之后,它不会再做任何事情,也不会调用任何析构函数,甚至不会打印函数create之后的消息 我正在使用Microsoft Visual Studio Community 2017版本15.9.17(如果有任何用途) 那么有没有解决这些问题的方法,或者我需要重新安装VisualStudio //期望C++ 为什么我的编译器不能按预期工作?,c++,visual-studio,compiler-errors,visual-studio-2017,C++,Visual Studio,Compiler Errors,Visual Studio 2017,我在multiply在线编译器上尝试了这段代码,它运行得很好,但是当我在我的计算机上尝试它时,出现了一些问题(虽然不完全是错误,但它没有按预期工作) 对于静态对象和gloabl对象都不调用析构函数。若我把函数create放在main后面,那个么在它调用create中对象的构造函数之后,它不会再做任何事情,也不会调用任何析构函数,甚至不会打印函数create之后的消息 我正在使用Microsoft Visual Studio Community 2017版本15.9.17(如果有任何用途) 那么有
Object 1 constructor runs (global before main)
MAIN FUNCTION: EXECUTION BEGINS
Object 2 constructor runs (local automatic in main)
Object 3 constructor runs (local static in main)
CREATE FUNCTIONS: EXECUTION BEGINS
Object 5 constructor runs (local automatic in create)
Object 6 constructor runs (local static in create)
Object 7 constructor runs (local automatic in create)
CREATE FUNCTION: EXECUTION ENDS
Object 7 destructor runs (local automatic in create)
Object 5 destructor runs (local automatic in create)
MAIN FUNCTION: EXECUTION RESUMES
Object 4 constructor runs (local automatic in main)
MAIN FUNCTION: EXECUTION ENDS
Object 4 destructor runs (local automatic in main)
Object 2 destructor runs (local automatic in main)
Object 6 destructor runs (local static in create)
Object 3 destructor runs (local static in main)
Object 1 destructor runs (global before main)
//实际
Object 1 constructor runs (global before main)
MAIN FUNCTION: EXECUTION BEGINS
Object 2 constructor runs (local automatic in main)
Object 3 constructor runs (local static in main)
CREATE FUNCTIONS: EXECUTION BEGINS
Object 5 constructor runs (local automatic in create)
Object 6 constructor runs (local static in create)
Object 7 constructor runs (local automatic in create)
CREATE FUNCTION: EXECUTION ENDS
Object 7 destructor runs (local automatic in create)
Object 5 destructor runs (local automatic in create)
MAIN FUNCTION: EXECUTION RESUMES
Object 4 constructor runs (local automatic in main)
MAIN FUNCTION: EXECUTION ENDS
Object 4 destructor runs (local automatic in main)
Object 2 destructor runs (local automatic in main)
如果我将函数create放在main后面,则默认
Object 1 constructor runs (global before main)
MAIN FUNCTION: EXECUTION BEGINS
Object 2 constructor runs (local automatic in main)
Object 3 constructor runs (local static in main)
CREATE FUNCTIONS: EXECUTION BEGINS
Object 5 constructor runs (local automatic in create)
Object 6 constructor runs (local static in create)
Object 7 constructor runs (local automatic in create)
CREATE FUNCTION: EXECUTION ENDS
#包括
使用std::cout;
使用std::endl;
类CreateAndDestroy{
公众:
CreateAndDestroy(int,const char*);//构造函数
~CreateAndDestroy();//析构函数
私人:
int objectID;
const char*消息;
}; // 结束类CreateAndDestroy
//建造师
CreateAndDestroy::CreateAndDestroy(int objectNumber,const char*messagePtr){
objectID=objectNumber;
message=messagePtr;
如果实际上没有调用析构函数,请签入调试器(或者通过在磁盘上保存一些日志,而不是使用std::cout
),这可能是在编译单元中定义的全局和静态对象的析构函数之前调用析构函数的“唯一”std::cout
请参阅:全局对象在执行main
函数之前构造,局部静态对象在执行函数体之前构造。局部静态对象在全局对象之前被销毁。它们都在main
函数之后
我测试了代码,效果很好。但是我在命令行编译中发现了这个问题。这应该是因为控制台在显示之前就消失了。我建议您可以添加以下代码
int main(int argc, char* argv) {
cout << "\nMAIN FUNCTION: EXECUTION BEGINS" << endl;
CreateAndDestroy second(2, "(local automatic in main)");
static CreateAndDestroy third(3, "(local static in main)");
create(); // call function to create objects
cout << "\nMAIN FUNCTION: EXECUTION RESUMES" << endl;
CreateAndDestroy fourth(4, "(local automatic in main)");
cout << "\nMAIN FUNCTION: EXECUTION ENDS" << endl;
getchar();
system("pause");
return 0;
} // end main ``
intmain(intargc,char*argv){
在你看来,什么时候应该调用静态实例的析构函数?我认为永远都不可能。全局析构函数也是如此。在离开main()之后,这也是一个关于此类析构函数执行顺序的问题。我记得在MFC时代(theApp…),全局变量容易出错的程度。此外,不建议在函数中使用静态变量,因为您无法重新创建定义的状态(例如用于测试)。@BitTickler静态初始化(和最终确定)顺序很棘手,但它在单个翻译单元中定义良好。-此外,您关于局部静态变量的建议有时是合理的,但局部静态有一些很好的推荐用途,它们覆盖了可测试性。文件范围内的静态(在一个翻译单元中)按照定义的顺序构造。函数块(或函数中的块)中的静态是在首次输入其包含块时构造的-这可以应用与同一编译单元中文件范围中的静态不同的顺序(即,不一定按照其定义在文件中出现的顺序)-我怀疑这与您预期的不同。不同编译单元中静态的构造顺序未指定。@BitTickler:您的假设是错误的。静态实例的析构函数肯定应该在main
返回后运行,例如,清理临时文件。回答得好!我的观点是,缺少arantee,任何设施在退出main(这里,std::cout)后仍然可以运行应该是足够的理由,在全局变量或模块全局变量中没有任何资源状态(例如,文件句柄、要清理的文件等)。并且,所有内存页都被删除并返回到系统(在大多数操作系统上,文件句柄等也会自动关闭),清理内存也不是一个问题。另一方面,依赖于main之后的清理的做法也会将泄漏检测变成一种病态情况。@BitTickler-在任何#包含头
标准流的源文件中(std::cin
,std::cout
,std::cerr
,和std::clog
,以及它们的std::wxxx
对应物)需要在源文件中定义的任何全局或静态对象之前构造。因此流都是有效的。并且,由于全局和静态对象按与其构造相反的顺序销毁,因此流在这些对象的析构函数之后才保持有效。(这有点简化,但对于本例来说是正确的。)
int main(int argc, char* argv) {
cout << "\nMAIN FUNCTION: EXECUTION BEGINS" << endl;
CreateAndDestroy second(2, "(local automatic in main)");
static CreateAndDestroy third(3, "(local static in main)");
create(); // call function to create objects
cout << "\nMAIN FUNCTION: EXECUTION RESUMES" << endl;
CreateAndDestroy fourth(4, "(local automatic in main)");
cout << "\nMAIN FUNCTION: EXECUTION ENDS" << endl;
getchar();
system("pause");
return 0;
} // end main ``