对应下面的代码和解析来学习这节知识,代码都是可运行的,在VS2012中就可以
#include
using namespace std;
#pragma warning(disable:4996);
/*
1.对象的生存周期
*/
class Object
{
public:
Object(int num)
{
cout << “Object::Object(int)” << endl;
mname = new char[1];
mnum = num;
}
Object(char* name = "",int num = 0)
{
cout << "Object::Object(char* ,int)" << endl;
mname = new char[strlen(name) + 1];
strcpy(mname, name);
Show();
if(num == 0)
{
mnum = strlen(mname) + 1;
}
else
{
mnum = num;
}
mnum = strlen(mname) + 1;
}
Object(const Object& rhs)//形参必须要引用
{
cout << "Object::Object(Object)" << endl;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mnum = rhs.mnum;
}
Object& operator = (const Object& rhs)
{
cout << "Object::operator=(Object)" << endl;
if(this != &rhs)
{
delete[] mname;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mname = rhs.mname;
}
return *this;
}
void Show()
{
cout << "name:" << mname << endl;
}
~Object()
{
cout << "Object::~Object()" << endl;
delete[] mname;
mname = NULL;//防止野指针出现
}
private:
char* mname;
int mnum;
};
Object gobj1(“globle Object1”);//(1)调用了一个char*类型的一个构造函数
static Object gobj2(“globle Object2”);//(2)
int main()
{
cout <<"------------------------------" << endl;
Object lobj1(“local Object1”);//(5)
cout <<"------------------------------" << endl;
Object lobj2(10);//(6)
static Object sobj("static object");//在调用点生成的(7)
Object lobj3 = lobj1;//调用拷贝构造函数生成的
lobj3 = lobj2;//调用赋值运算符的重载函数
Object* pobj4 = new Object("local Object4");//在堆内存上生成了一个堆的对象,
//生成好了以后地址给了栈上的一个指针,等号的右边来说地址是在堆上开辟的,
//等号的左边这个指针的地址是在栈上开辟的,也就是说栈上的指针指在堆上的一个对象了
//这个对象只有遇到delete的时候才销毁
cout <<"------------------------------" << endl;
Object abj5[2];//生成了对象的数组,有两个对象的生成,他调用的是默认的构造函数
cout <<"------------------------------" << endl;
Object* pobj6 = &Object("local Object");//等号的右边来说生成了一个显示生成临时对象,
//把显示生成临时对象的地址给了栈上的指针了,栈上的指针指向了一个临时对象,
//临时对象再遇到分号的时候销毁了,所以说这行代码有对象的销毁
Object& pobj7 = (Object)("local object7",20);//逗号表达式取得是20的值,
//到时候调用一个带有整形参数的构造函数来生成了一个临是对象,这是一个显示生成临时对象的过程
//引用会提升临是对象的生存周期,所以期间不需要销毁对象,pobj6和pobj7的生存周期一样了
Object& pobj8 = *(new Object("local Object8 "));//在堆上生成了一个对象,
//堆上给咱们生成的是指针,堆上给咱们返回的是地址,
Object obj9 = "object9";//等价于Object obj9("object9");
delete pobj4;//四号对象的销毁
cout <<"------------------------------" << endl;
Object obj10 = Object("Object10");//等号的右边是显示生成临时对象,
//调用拷贝构造函数对这个新对象进行构造拿这个已生成的临时对象,
//但是你会发现整个函数当中只有一个函数的调用,只有一个对象的生成
//没有临时对象的生成,因为系统做优化了
//如果临时对象生成的目的就是为了构造我这个新的对象,那我直接以生成临时对象的方式生成新对象了
obj9 = Object("object11");//因为等号的右边生成一个临时对象,
//是来给一个已存在的对象进行赋值的,编译器还会不会优化,就不会优化了,这两行代码有两个对象的生成
return 0;
}
Object gobj3(“globle Object3”);//(3)
static Object gobj4(“globle Object4”);//(4)
//int main()
//{
// //Object obj = “Object”;//等同于这种代码Object obj (“Object”);
// //执行流程
// //调用构造函数
//
// Object obj = (Object)(“Object”,10);//这一行代码又是干什么的呢?
// //等号的右边显示生成了一个临时对象,只有一个对象的生成
// return 0;
//}
!
//int main()
//{
// /*
// 临时对象的作用
// 就是为了生成新对象
// 编译器给优化掉了
// 已生成临时对象的方式来生成新的对象
// */
// Object obj = Object(“Object”);//等号的右边是显示生成临时对象
// //这一行代码中有几个对象的生成
// //只有一个对象的生成
// return 0;
//}
//int main()
//{
// Object* pobj = &Object(“Object”);//显示生成临时对象,然后取临时对象的地址
// //问题,这一行代码的调用中有几个函数的调用
// //两个,调用构造函数,析构函数
// cout << “----------------------------” << endl;
//
// Object& pobj1 = Object(“Object”);//等号的右边是显示生成临时对象,然后等号的左边引用这个对象
// //引用会提升临时对象的生存周期,从调用点到main函数结束
// cout << “----------------------------” << endl;
// return 0;
//}
//int main()
//{
// Object obj1(“Object”);
// Object* pobj = new Object(“Object heap”);//pobj这个指针实在堆上开辟的
// //问题:现在这个代码有几个函数的调用
// //构造函数、析构函数、new的构造函数、new所对应的delete得手动操作,所以说先销毁的时候销毁的是obj1
// delete pobj;
// cout << “***********************************” << endl;
// return 0;
//}
//void Func(Object obj)
//{
// Object tmp(obj);//接受了一个obj对象,然后又生成了一个tmp对象
//}
//int main()
//{
// Object ob1(“object1”);//生成了一个对象
// Func(ob1);//整个代码生成了几个对象
// //现在有两个对象生成,ob1,tmp,但是实参传形参的过程有对象的生成
// //形参要开辟内存,所以会生成obj这个对象
// return 0;
//}
//void Func(Object& obj)
//{
// Object tmp(obj);//接受了一个obj对象,然后又生成了一个tmp对象
//}
//int main()
//{
// Object ob1(“object1”);//生成了一个对象
// Func(ob1);//整个代码生成了几个对象
// //现在有两个对象生成,ob1,tmp,但是实参传形参的过程有对象的生成
// //形参是对象类型,建议大家使用引用,这个时候就没有obj这个对象的生成了,效率变高了,少了两个函数的调用
// return 0;
//}