多玩YY语音的面试题:C++中如何在main()函数之前执行操作?

简介: 第一反应main()函数是所有函数执行的开始。但是问题是main()函数执行之前如何执行呢? 联想到MFC里面的 C**App类的theApp对象,其执行顺序就在main函数之前。道理相通,顺理推下,能够想到:如果在main函数之前声明一个类的全局的对象。那么其执行顺序,根据全局对象的生存期和作用域,肯定先于main函数。

多玩YY语音的面试题:C++中如何在main()函数之前执行操作?


          第一反应main()函数是所有函数执行的开始。但是问题是main()函数执行之前如何执行呢?


          联想到MFC里面的 C**App类的theApp对象,其执行顺序就在main函数之前。道理相通,顺理推下,能够想到:如果在main函数之前声明一个类的全局的对象。那么其执行顺序,根据全局对象的生存期和作用域,肯定先于main函数。


示例如下:


class simpleClass

{

public:

      simpleClass( )

      {

             cout << "simpleClass constructor.." << endl;  //step2

      }

};

simpleClass g_objectSimple;         //step1全局对象

int _tmain(int argc, _TCHAR* argv[])  //step3

{

      return 0;

}

可单步调试查看执行顺序为step1、step2、step3。


考虑到全局对象,同理会进一步思考静态对象的作用域。将上述示例进一步扩展如下:


class simpleClass

{

public:

      simpleClass( )

      {

             cout << "simpleClass constructor.." << endl;       //step2

      }

};

class simpleClassTwo

{

public:

      static simpleClass m_sSimpleClass;

};

simpleClass simpleClassTwo::m_sSimpleClass = simpleClass(); //step1 静态对象

int _tmain(int argc, _TCHAR* argv[])                        //step3

{

       return 0;

}

可单步调试查看执行顺序为step1、step2、step3。

       至此,我们可以总结出:定义在main( )函数之前的全局对象、静态对象的构造函数在main( )函数之前执行。


     再进一步思考,既然可以在main( )函数之前执行全局、静态对象的构造函数。那么有没有函数在main( )函数之后执行呢?


有的,onexit函数。原型如下:


_onexit_t _onexit(


  _onexit_t function


);


_onexit_t_m _onexit_m(


  _onexit_t_m function


);


解释:The _onexit function is passed the address of a function (function) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to _onexit cannot take parameters.



核心点:


1)              执行期——程序执行终止的时候;


2)              传递参数——函数的地址,即函数指针;


3)              执行顺序——后进先出。



_onexit is a Microsoft extension. For ANSI portability, use atexit. The _onexit_m version of the function is for mixed mode use.


onexit是微软的扩展版本,标准C++里面应用的是atexit。


【MSDN】示例:


#include <stdlib.h>

#include <stdio.h>

/* Prototypes */

int fn1(void), fn2(void), fn3(void), fn4 (void);

int main( void )

{

     _onexit( fn1 );

     _onexit( fn2 );

     _onexit( fn3 );

     _onexit( fn4 );

     printf( "This is executed first.\n" );

}

int fn1()

{

     printf( "next.\n" );

     return 0;

}

int fn2()

{

     printf( "executed " );

     return 0;

}

int fn3()

{

     printf( "is " );

     return 0;

}

int fn4()

{

     printf( "This " );

     return 0;

}

执行结果如下:

————————————————

版权声明:本文为CSDN博主「铭毅天下」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/laoyang360/article/details/8820501

相关文章
|
7月前
|
缓存 安全 编译器
C++面试周刊(3):面试不慌,这样回答指针与引用,青铜秒变王者
《C++面试冲刺周刊》第三期聚焦指针与引用的区别,从青铜到王者级别面试回答解析,助你21天系统备战,直击高频考点,提升实战能力,轻松应对大厂C++面试。
661 132
C++面试周刊(3):面试不慌,这样回答指针与引用,青铜秒变王者
|
9月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
229 0
|
12月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
718 6
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
654 6
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
184 3
|
安全 编译器 C++
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
【C++篇】C++类与对象深度解析(三):类的默认成员函数详解
152 3
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
362 0
C++ 多线程之线程管理函数
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
2777 1
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
229 1