目录
定义:
浅拷贝:
类类型作为函数的形参:
类类型作为函数返回值:
定义:
同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。在建立对象时可用同一类的另一个对象来初始化该对象的存储空间,这时所用的构造函数成为拷贝函数。
#includeclass Complex { private: int real; int image; public: Complex():real(0),image(0){} Complex(int r,int i):real(r),image(i){} Complex(const Complex &com) //拷贝构造函数,不能对被拷贝的值进行修改因此加上const修饰,形参 //使用引用,不能使用值传递,造成无穷递归 { real=com.real; image=com.image; } //拷贝构造函数属于构造函数的一种重载,因此可以采用初始化列表 Complex(const Complex &com):real(com.real),image(com.image) //先构造real和Image再进入构造 //函数体内部 { cout<<"Copy Create Complex(const Complex &)"< 总结:
拷贝构造函数的参数--采用引用。如果把一个真实的类对象作为参数传递到拷贝构造函数,会引起无穷递归。
在类中如果没有显式给出拷贝构造函数时,则c++编译器自动给出一个缺省的拷贝构造函数。如果有程序设计者定义的构造函数(包括拷贝构造函数),则按函数重载的规律,调用合适的构造函数。
缺省的拷贝构造函数的特点:按位拷贝。
浅拷贝:
class CGoods { private: enum {LEN=20}; char Name[LEN]; int Amount; float Price; float Total_value; public: CGoods():Name{},Amount{},Price{},Total_value{} { //memset(this,0,sizeof(CGoods)); 不得在构造函数中使用mem,由于虚表和虚函数特性 } CGoods(const char* name,int amount,float price) { strcpy_s(Name,LEN,name);//字符串的赋值必须采用strcpy Amount=amount; Price=price; Total_value=amount*price; } CGoods(const Cgoods &c) { //memcpy(this,&c,sizzeof(CGoods)); 也会将虚表修改掉,不可以这样写 //Name=c.Name; 这样也是错误的,必须使用strcpy_s拷贝 strcpy_s(Name,LEN,c.Name); Amount=c.Amount; Price=c.Price; Total_value=c.Total_value; cout<<"Copy CGoods(const Cgoods &)"<类类型作为函数的形参:
1. 值传递 2.引用传递 3.常引用传递
void funa(CDate dt) //首先构造dt,再传入da1对dt进行初始化构造,将值传入 { } void funb(CDate & dt) //直接以引用传入,会修改到实参的值 { } void func(const CDate&dt) //只引用值,不修改 { } int main() { CDate da1(2022,6,8); CDate da2(da1); funa(da1); return 0; }类类型作为函数返回值:
1.函数的返回只能以类的值返回,不能以引用返回。
2.如果函数的返回值不受函数生存期的影响,就可以以引用返回。
CDate get_CDate_1() //以值返回的话,返回值给主函数时会构造一个临时对象(将亡值) { CDate dt(2025,4,5); return dt; } CDate get_CDate_2() { return CDate(2025,4,9); //直接在main中构造临时对象并返回 } CDate & get_CDate_3() //不能用引用返回,在函数调用后函数的栈空间被回收。如果对象生存期不受函数 //影响,可以采用左值引用返回 { CDate dt(2025,4,5); return dt; } CDate& get_CDate_4() { return CDate(2025,4,9); //临时对象在c11中属于右值,不能以左值引用返回 } CDate&& get_CDate_5() { return CDate(2025,4,9); //构造完临时对象后,立马析构掉临时对象,如果以引用返回,将返回失败 } int main() { CDate dta; dta=get_CDate_1(); //临时对象将值赋给dta,后析构掉自身 dta.ShowDate(); return 0; }



