对象生存期也称对象生命周期,是指对象从被创建到被释放的时间。按生存期的不同,对象可分为局部对象、静态对象、全局对象和动态对象4种。
1.局部对象
局部对象是指定义在一个程序块或函数体内的对象,包括形参。当定义对象时,系统自动调用构造函数,该对象被创建,对象的生存期开始。当退出该函数体或程序块时,调用析构函数,释放该对象,对象的生存期结束。
#include <iostream>
using namespace std;
class A //测试对象生存期的类
{
public:
A(int i):id(i) //构造函数
{
cout << "id="<<id<<"对象被创建了" << endl;
}
A(const A& ca)//拷贝构造函数
{
id = ca.id;
cout <<"拷贝构造: "<<"id = " << id << "对象被创建了" << endl;
}
~A()
{
cout << "id=" << id << "析构,对象被销毁!" << endl;
}
private:
int id; //编号,用于区分不同的对象
};
void test1(A b)
{
cout << "进入,test1()" << endl;
cout << "test1()结束" << endl;
}
void test2()
{
cout << " 进入,test2()" << endl;
A c(3);
cout << " test2()结束" << endl;
}
int main()
{
cout << "进入,main()" << endl;
A a(1);
test1(a);
test2();
cout << "main()结束" << endl;
return 0;
}
程序执行结果如下:
代码分析如下:
第45行A a(1);创建对象a,a是main函数内部的局部变量,当main函数结束时该对象被销毁。
第46行test1(a);由于第25行void test1(A b)是非引用的对象传递,调用拷贝构造函数创建对象b,该对象是test1的局部变量,当test1结束时对象b被销毁。
第47行test2();在这个函数内部,第36行执行A c(3);定义局部对象c,当test2函数结束时对象c被销毁。
2.静态对象
静态对象是指以关键字 static 标识的对象。当第一次定义对象时,系统自动调用构造函数,该对象被创建,对象的生存期开始。当程序(进程)结束时调用析构函数,该对象被释放,对象的生存期结束。因此,静态对象的生存期从第一次定义该对象时开始,到整个程序(进程)结束时终止。
#include <iostream>
using namespace std;
class A //测试对象生存期的类
{
public:
A(int i):id(i) //构造函数
{
cout << "id="<<id<<"对象被创建了" << endl;
}
~A()
{
cout << "id=" << id << "析构,对象被销毁!" << endl;
}
private:
int id; //编号,用于区分不同的对象
};
class B
{
public:
B() //构造函数
{
cout << "B对象被创建了" << endl;
}
~B()
{
cout << "B析构,对象被销毁!" << endl;
}
private:
static A a; //静态成员变量
};
A B::a = A{ 1 }; //初始化B中的静态成员 a
static A bb{ 2 };//静态对象
void test3()
{
cout << "进入test3()" << endl;
static A cc{ 3 };
cout << "退出test3()" << endl;
}
int main()
{
cout << "进入main()" << endl;
test3();
static A dd = {4};
cout << "退出main()" << endl;
return 0;
}
执行结果如下:
输出语句调用位置如下图:
3.全局对象
全局对象是指定义在函数体外的对象。它的生存期从程序(进程)运行开始到程序(进程)结束时终止。当程序开始时,系统自动调用构造函数,该对象被创建,对象的生存期开始。当程序结束时调用析构函数,该对象被释放,对象的生存期结束。
class A //测试对象生存期的类
{
public:
A(int i):id(i) //构造函数
{
cout << "id="<<id<<"对象被创建了" << endl;
}
~A()
{
cout << "id=" << id << "析构,对象被销毁!" << endl;
}
private:
int id; //编号,用于区分不同的对象
};
A g_a{ 1 };//全局对象
A g_b{ 2 };//全局对象
static A g_c{ 3 };//全局静态对象
static A g_d{ 4 };//全局静态对象
int main()
{
cout << "进入main()" << endl;
cout << "退出main()" << endl;
return 0;
}
程序执行结果如下:
从上面结果能看见,全局对象在进入main函数前已经被创建,在main函数结束后才被释放。
4.动态对象
动态对象是指以运算符new创建,以运算符delete释放的对象。当程序执行运算符new时创建该动态对象,对象的生存期开始。当执行运算符delete时释放该动态对象,对象的生存期结束。因此,动态对象的生存期从运算符new创建时开始,到以运算符delete释放时终止。
例如:下面的程序动态创建对象,但没有释放
class A //测试对象生存期的类
{
public:
A(int i):id(i) //构造函数
{
cout << "id="<<id<<"对象被创建了" << endl;
}
~A()
{
cout << "id=" << id << "析构,对象被销毁!" << endl;
}
private:
int id; //编号,用于区分不同的对象
};
A* test4()
{
cout << "进入test4()" << endl;
A* p = new A{20};
cout << "退出test4()" << endl;
return p;
}
int main()
{
cout << "进入main()" << endl;
A* p1 = test4();
cout << "退出main()" << endl;
return 0;
}
请注意:上面的动态对象没有使用delete释放,出现内存泄漏。
例如:动态对象的创建和释放
#include <iostream>
using namespace std;
class A //测试对象生存期的类
{
public:
A(int i):id(i) //构造函数
{
cout << "id="<<id<<"对象被创建了" << endl;
}
~A()
{
cout << "id=" << id << "析构,对象被销毁!" << endl;
}
private:
int id; //编号,用于区分不同的对象
};
A* test4()
{
cout << "进入test4()" << endl;
A* p = new A{20};
cout << "退出test4()" << endl;
return p;
}
int main()
{
cout << "进入main()" << endl;
A* p1 = test4();
delete p1;
cout << "动态创建对象数组" << endl;
A* p2 = new A[5]{1,2,3,4,5};
delete[]p2;//释放动态创建的数组需要加[
cout << "退出main()" << endl;
return 0;
}
程序输出的语句如下: