对象的生存周期
#include<iostream>
class Test
{
public:
Test()
{
std::cout << this << " :Test::Test()" << std::endl;
ma = mb = 0;
}
Test(int a)
{
std::cout << this << " :Test::Test(int)" << std::endl;
ma = a;
mb = 0;
}
Test(int a, int b)
{
std::cout << this << " :Test::Test(int, int)" << std::endl;
ma = a;
mb = a;
}
Test(const Test& rhs)//const的作用:1.防止通过形参修改实参的值 2.接受隐式生成的临时量
{
std::cout << this << " :Test::Test(const Test&)" << std::endl;
ma = rhs.ma;
}
Test& operator=(const Test& rhs)//连续赋值
{
std::cout << this << " :Test::operator=(const Test&)" << std::endl;
if (this != &rhs)
{
ma = rhs.ma;
}
return *this;
}
~Test()
{
std::cout << this << " :Test::~Test()" << std::endl;
}
private:
int ma;
int mb;
};
int main()
{
Test test1;//Test <== int
test1 = 20;//Test <== Test
Test test2 = 20;//<==>Test test2(20);
//Test::Test(int) ==> 生成临时对象
//Test::Test(const Test&) ==> 生成新对象test2
//Test::~Test() ==> 销毁临时对象
return 0;
}
内置类型 ==> 自定义类
1.内置类型 ==> 临时对象
临时对象的生存周期:表达式结束(; , ?),调用析构函数销毁
临时对象的优化:如果临时对象的生存目的,是为了生成新的对象,则以生成临时对象的方式来生成新对象
临时量:
1.临时变量(内置类型生成的临时量)(常量)
2.临时对象(自定义类型生成的临时量)(变量)
3.隐式生成的临时量是常量
隐式生成与显式生成
隐式生成:如果生成的变量是由编译器推演类型得出,则为隐式生成
显式生成:由程序人员明确指出
Test gtest1(1);//数据段 调用带有一个整形参数的构造函数生成 程序结束后调用析构函数销毁
static Test gtest2(1, 3);//数据段 调用带有两个整形参数的构造函数生成 程序结束后调用析构函数销毁
int main()
{
Test ltest1(10);//stack 调用带有一个整型参数的构造函数生成 生存周期:从调用点到return后 析构函数销毁
Test ltest2(ltest1);//stack 调用拷贝构造函数生成 生存周期:从调用点到main函数结束 析构函数销毁
static Test ltest3(20, 30);//数据段 调用带有一个整形参数的构造函数生成 生存周期:从调用点到整个程序结束 析构函数销毁
ltest1 = 40;//stack 构造函数 赋值运算符重载函数 析构函数 隐式生成临时对象
ltest1 = Test(50);//stack 构造函数 赋值运算符重载函数 析构函数 显式生成临时对象
ltest1 = (Test)(60, 70 , 90 , 100, 100 ,200 ,300);//逗号表达式(选择列表中最后一个数据)将列表数据强转<==>ltest1=(Test)(300) stack 构造函数 赋值运算符重载函数 析构函数 显式生成临时对象
Test ltest4 = 80;//调用构造函数 显式生成临时对象优化,生成新对象
Test ltest5 = Test(90);//构造函数,只有ltest5生成
Test* ptest6 = new Test(100);//在堆上生成一个对象,调用默认的构造函数,将地址赋给ptest6,到delete结束
Test* ptest7 = new Test[2];//在堆上开辟数组生成两个对象,调用默认的构造函数
delete[] ptest7;//两个析构函数,销毁new出的对象
Test* ptest8 = &Test(110);//显式生成临时对象,将地址赋给ptest8,可能会造成野指针 构造函数 析构函数
Test& rtest9 = Test(120);//显式生成临时对象,rtest9引用,只有构造函数,没有析构函数,在return销毁 原因:引用会提升临时对象的生存周期,把临时对象的生存周期提升的和引用变量相同的生存周期
//const Test& rtest10 = 130;//error 引用不能引用不能取地址的数据
const Test& rtest11=130;//130=Test(130)=>const& 引用 构造函数
delete ptest6;
return 0;
}
Test gtest3(2);//数据段 调用带有一个整形参数的构造函数生成 程序结束后调用析构函数销毁