C++中四种不同的对象生存方式(in stack, in heap, global, local static)

在C++中,有4种方法可以产生一个对象.

第一种方法是在堆栈 (stack) 之中产生它:

void TestFunc()
{
    CUser user;  //在堆栈 (stack) 中产生user对象
}

 第二种方法是在堆积 (heap) 之中产生它:

void TestFunc()
{
   CUser* pUser = new CUser(); //在堆积 (heap) 中产生对象
}

 第三种方法是产生一个全局对象 (同时也必然是个静态对象)

CUser user; //在任何函数范围之外做此动作

第四种方法是产生一个局部静态对象

void TestFunc()
{
  static CUser user;  //在函数范围 (scope) 之内的一个静态对象
}

 上面四种方法中,无论是哪一种做法,C++都会产生一个针对Cuser构造函数的调用动作。 

对于第一种和第二种情况,C++在配置内存 -- 来自堆栈(stack) 或者 堆积 (heap) 后,之后立刻就会产生一个隐藏 (你的原始代码中看不出来的) 构造函数调用

但是针对第三种情况,由于全局对象实现于任何 [函数活动范围 function scope] 之外,显然没有地方来安置它的构造函数调用动作  =》  这种静态全局对象,它的构造函数调用动作必须靠startup代码帮忙. 

startup代码是什么?是更早于程序进入点(main 或 WinMain)执行起来的代码,由 C++ 编译器提供,被链接到你的程序中。startup 代码可能做些像函数库初始化、进程信息设立、I/O stream 产生等等动作,以及对 static 对象的初始化动作(也就是调用其构造函数)。

当编译器编译你的程序,发现一个静态对象,它会把这个对象加到一个串列之中。更精确地说则是,编译器不只是加上此静态对象,它还加上一个指针,指向对象之构造函数及其参数(如果有的话)。把控制权交给程序进入点(main 或 WinMain)之前,startup代码会快速在该串列上移动,调用所有登记有案的构造函数并使用登记有案的参数,于是就初始化了你的静态对象。

 

第四种情况 (局部静态对象) ,相当类似C语言中的静态局部变量,只会有一个实体(instance)产生,而且在固定的内存上(既不是stack 也不是heap)。它的构造函数在控制权第一次移转到其声明处(也就是在MyFunc第一次被调用)时被调用。

posted on 2024-04-18 16:03  新西兰程序员  阅读(9)  评论(0编辑  收藏  举报