创建对象的过程(临时对象)
class CGoods
{
public:
CGoods(char* name, int amount, float price)
{
std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
mname = new char[strlen(name) + 1];
strcpy(mname, name);
mamount = amount;
mprice = price;
}
CGoods()
{
std::cout << this << " :CGoods::CGoods()" << std::endl;
mname = new char[1];
}
CGoods(float price)
{
std::cout << this << " :CGoods::CGoods(float)" << std::endl;
mname = new char[1];
mprice = price;
}
CGoods(const CGoods& rhs)
{
std::cout << this << " :CGoods::CGoods(const CGoods& )" << std::endl;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
/*
const
1.防止实参被修改
2.接收隐式生成的临时量
*/
CGoods& operator=(const CGoods& rhs)
{
std::cout << this << " :CGoods::operator=(const CGoods&) <<==" << &rhs << std::endl;
if (this != &rhs)
{
delete[] mname;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
return *this;
}
~CGoods()
{
std::cout << this << " :CGoods::~CGoods()" << std::endl;
delete[] mname;
mname = NULL;
}
private:
char* mname;
int mamount;
float mprice;
};
CGoods good1("good1", 1, 1.1);//.data
int main()
{
CGoods good3;//
CGoods good4(17.5f);
CGoods good5("good5", 5, 5.5);
static CGoods good6("good6", 6, 6.6);
good3 = 17.5f;
good3 = CGoods(17.5f);
good3 = (CGoods)("good3", 3, 3.3);
CGoods good7 = 17.5f;
CGoods good8 = CGoods("good8", 8, 8.8);
CGoods* pgood9 = new CGoods("good9", 9, 9.9);
CGoods* pgood10 = new CGoods[2];
CGoods* pgood11 = &CGoods("good11", 11, 11.11);
//CGoods& rgood12 = CGoods("good12", 12, 12.12);
const CGoods& rgood13 = 17.5f;
delete[] pgood10;
delete pgood9;
return 0;
}
CGoods good2("good2", 2, 2.2);//.data
下面对运行结果分析:
CGoods good1("good1", 1, 1.1);;
调用带三个参数的构造函数(堆区)CGoods good2("good2", 2, 2.2);
调用带三个参数的构造函数(堆区)CGoods good3;
调用不带参数的构造函数(栈区)CGoods good4(17.5f);
调用带一个参数的构造函数(栈区)CGoods good5("good5", 5, 5.5);
调用带三个参数的构造函数(栈区)static CGoods good6("good6", 6, 6.6);
调用带三个参数的构造函数(堆区)good3 = 17.5f;
赋值运算符两端数据类型不匹配,右侧隐式生成临时量,推演CGoods中有符合自身数据类型的构造函数,赋值运算符左侧为已有的对象则不会优化,总的调用顺序是首先生成临时量调用带一个参数的构造函数,其次调用赋值运算符的重载函数,从地址可以看出,其次赋值完成,临时量调用析构函数good3 = CGood(17.5f);
赋值运算符右侧显示生成临时量,调用CGood中带一个参数的构造函数,然后同上。good3 = (CGood)("good3", 3, 3.3);
这里包含一个逗号运算符(用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值),此时也就和显式生成临时量一样了。CGoods good7 = 17.5f;
赋值运算符右侧隐式生成临时量,推演CGoods中有符合自身数据类型的构造函数,赋值运算符左侧是生成新对象则会产生优化,以生成临时对象的方式生辰新对象,故调用带一个参数的构造函数。(不需要调用赋值运算符重载函数)。CGoods good8 = CGoods("good8", 8, 8.8);
赋值运算符右侧显式生成临时量,赋值运算符左侧是生成新对象则会产生优化,以生成临时对象的方式生成新对象,故调用带三个参数的构造函数。CGoods* pgood9 = new CGoods("good9", 9, 9.9);
使用new关键字来生成新对象,新对象的位置在堆区,所以打印出的地址与上面的有很大差别,调用带三个参数的构造函数。
CGoods* pgood10 = new CGoods[2];使用new关键字来生成对象数组,所以会调用两次带三个参数的构造函数。CGoods* pgood11 = &CGoods("good11", 11, 11.11);
赋值运算符两端数据类型不匹配,右侧显式生成临时量,但是左侧非对象,而是指针,将临时对象的地址赋给指针pgood11,在;
之后临时对象就会释放,调用顺序是带三个参数的构造函数、析构函数;这里使pgood11成为野指针,所以应该p = NULL;
CGoods& rgood12 = CGoods("good12", 12, 12.12);
赋值运算符右侧显式生成临时对象,使用引用给临时对象起别名,同时会使临时对象的生命周期增长。const CGoods& rgood13 = 17.5f;
这里要对临时量进行说明,临时量包括三种:
1.内置类型生成的临时量是常量(临时量,寄存器带出来)。
2.自定义类型生成的临时量是变量 ,在内存中。
3.隐式生成生成的临时量是常量 ,显式生成生成的临时量是变量 。
所以当引用常量时必须使用const修饰,调用带一个参数的构造函数。