拷贝构造函数

目录

定义:

浅拷贝:

类类型作为函数的形参:

类类型作为函数返回值:


定义:

      同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。在建立对象时可用同一类的另一个对象来初始化该对象的存储空间,这时所用的构造函数成为拷贝函数。

#include<iostream>
class 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 &)"<<endl;
}//按位拷贝
};
void fun(Complex cs)  //使用值传递,拷贝构造形参
{
 
}
int main()
{
    Complex ca;
    Complex cb(1,2);
    Complex cc(cb);    //拷贝构造

return 0;
}

总结:

       拷贝构造函数的参数--采用引用。如果把一个真实的类对象作为参数传递到拷贝构造函数,会引起无穷递归。

       在类中如果没有显式给出拷贝构造函数时,则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 &)"<<endl;
}


};
int main()
{
   CGoods book("C++",10,128.0);
   CGoods bx(book);
   return  0;
}

类类型作为函数的形参:

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值