对象的生成:1、开辟内存
2、系统调用构造函数对开辟内存进行初始化
1、构造函数:构造函数名称和类名相同 有this指针
默认构造函数CGoods() {} 没有参数,可以重载
构造函数没有办法手动调动,只能系统调动
CGoods good1("面包",2,5);
CGoods good2;//调用默认构造函数
CGoods good3();//函数声明
2、析构函数:~CGoods
~CGoods()
{
delete[] mname;
mname = NULL;
}
对象的销毁:
1、资源的释放(释放对象所占其他资源)
2、释放内存
析构函数:1、有this指针 2、不能重载 3、可以手动调用,这时析构函数退化成普通的成员方法,所以一般由系统调用
~CGoods()
{
delete[] this->name;//系统默认有this指针
}
3、拷贝构造函数:用已存在的对象初始化新的对象
1、默认拷贝构造函数做浅拷贝(如果类成员变量有指针,考虑深拷贝)
2、形参一定要是对象的引用==》否则递归生成形参对象,形参对象无法生成
3、拿一个已存在的对象来生成相同类型的新对象
4、赋值运算符的重载函数:拿一个已存在的对象给一个相同类型的已存在的对象赋值,默认的赋值运算符重载函数是浅拷贝
1、自赋值判断
2、释放旧资源
3、开辟新资源
4、赋值
#include<iostream>
//构造函数 初始化对象的内存空间
//析构函数 释放对象所占资源
//拷贝构造函数
//赋值运算符的重载函数
//能不能自己调用构造函数和析构函数
//1、构造函数不可以自己调用,1、类的成员方法依赖对象调用(对象的生成要调用构造函数)2、构造完成后对象才生成
//2、析构函数调用前,对象存在,可以自己调用,析构函数自己调用时,退化成一个普通的成员方法,调用完成后,系统还会调用析构函数再次释放
//导致同一块内存释放两次,不建议自己去调用
//默认的构造函数和默认的析构函数,不带任何参数
//用户提供系统就不会提供
//默认的构造函数调用的方式
/*
拷贝构造函数:拿一个已存在的对象来生成一个相同类型已存在的对象
*/
class CGoods
{
public:
CGoods(char* name,float price,int amount)//构造函数,初始化成员对象,有this指针(初始化哪一个对象)
{
//构造函数可以重载
std::cout << this << "CGoods::CGoods(char*,float,int)" << std::endl;
//mname = name;
mname = new char[strlen(name)+1];
strcpy(mname,name);
mprice = price;
mamount = amount;
}
CGoods()
{
std::cout <<this<< "CGoods::CGoods()"<<std::endl;
}
/*CGoods(const CGoods& rhs)//拷贝构造函数,一个简单的复制过程
{
mname=rhs.mname;//指向同一块内存,再次释放堆内存时,导致释放野指针程序崩溃,这种就是浅拷贝
mprice= rhs.mprice;
mamount = rhs.mamount;
}*/
//赋值运算符的重载函数,拿一个已存在的对象给另一个已存在个对象赋值
//有自赋值判断 浅拷贝
//CGoods& operater=(const CGoods& rhs)
//{
// if(this ==&rhs)
// {
// return *this;
// }
// mname= rhs.mname;
// mprice = rhs.mprice;
// mamount=rhs.mamount;
// return *this;
//}
void operator=(const CGoods& rhs)//赋值运算符的重载函数,深拷贝
{
std::cout << this << " :CGoods::opreator=(CGoods)"<<std::endl;
if(this !=&rhs)
{
delete[] mname;
mname = new char[strlen(rhs.mname)+1];
strcpy(mname,rhs.mname);
mprice = rhs.mprice;
mamount=rhs.mamount;
}
}
//拷贝构造函数的引用不能去掉,形参对象构造不出来,引用没有新的对象生成
CGoods(const CGoods& rhs)//拷贝构造函数,实现深拷贝,如果成员变量中有指针,要自己重新写
{
std::cout << this<< "CGoods::CGoods(CGoods)"<<std::endl;
mname = new char[strlen(rhs.mname)+1]();
strcpy(mname,rhs.mname);
mprice = rhs.mprice;
mamount=rhs.mamount;
}
CGoods(char*name)//构造函数重载
{
std::cout <<this<< "CGoods::CGoods(char*)"<<std::endl;
mname = new char[strlen(name)+1]();//()初始化一下
strcpy(mname,name);
}
~CGoods()//析构函数,有this指针
{
//析构函数不能重载,为了释放对象所占资源,把所有资源按照同一方式释放
std::cout << this << "~CGoods()" << std::endl;
delete[] mname;//释放堆内存
mname=NULL;
}
void Show()//CGoods* const this每一个普通成员方法中默认有CGoods* const 的this指针存在,形参是系统提供的
{
//this =good2;//让指针指向good2,如果指向改变打印good2的地址
std::cout<<"name:"<<mname<<std::endl;//普通成员函数,打印商品名称
}
private:
char* mname;
float mprice;
int mamount;
};
int main()
{
CGoods good1("good1",20.1f,10);//good1调用构造函数,good2调用拷贝构造函数
CGoods good2 = good1;//拿一个已存在的对象构造一个相同类型已存在的对象,拷贝构造函数
//CGoods good3;
//good1 = good2;
//good3 = "good3";
return 0;
}
/*int main()
{
CGoods good1("good1",1000,20);//good1对象先生成,good2对象后生成
//good1="good2";
CGoods good2("good2",2000,10);
CGoods good3("goodg3");//构造函数,重载
//good1.Show(&good2);//
good1.Show();//this指针指向对象的内存,good2先销毁,good1后销毁,在栈上开辟的内存
good2.Show();//类的成员方法依赖对象调用
//good3.~CGoods();//手动调用析构函数
//CGoods good5;//对象生成,调用默认的构造函数,用户提供系统不会提供
//CGoods good4();//调用默认的构造函数后面不需要加括号,会让编译器产生二义性(函数声明)
//int Sum();//函数声明,在链接中会把没有调用的函数符号删除
return 0;
}*/