格式

classname (const classname &obj) {
   // 构造函数的主体
}

将 对象的 应用做为参数传入

1.对象做为参数 传入 函数

class CExample 
{
	private:
	 int a;

	public:
	 //构造函数
	 CExample(int b)
	 { 
		 a = b;
		 cout<<"creat: "<<a<<endl;
	 }

	 //拷贝构造
	 CExample(const CExample& C)
	 {
			a = C.a;
			cout<<"copy"<<endl;
	 }
 
	 //析构函数
	 ~CExample()
	 {
	  cout<< "delete: "<<a<<endl;
	 }

     void Show ()
		 {
         cout<<a<<endl;
     }
};

//全局函数,传入的是对象
void g_Fun(CExample C)
{
 cout<<"test"<<endl;
}

int main()
{
	 CExample test(1);
	 //传入对象
	 g_Fun(test);

	 return 0;
}

会调用 拷贝构造函数 将 需要传入 test 拷贝构造给 C (局部变量)

2.对象以值传递的方式从函数返回

class CExample 
{
private:
 int a;

public:
 //构造函数
 CExample(int b)
 { 
  a = b;
 }

 //拷贝构造
 CExample(const CExample& C)
 {
  a = C.a;
  cout<<"copy"<<endl;
 }

     void Show ()
     {
         cout<<a<<endl;
     }
};

//全局函数
CExample g_Fun()
{
 CExample temp(0);
 return temp;
}

int main()
{
 g_Fun();
 return 0;
}

g_Fun() 当调用的 返回一个 类 但是返回的时候 进行的操作为

  1. 会创建一个新的对象(临时变量)叫做 XXX
  2. 调用拷贝构造函数 类似 CExample XXX(temp)
  3. 然后析构掉 temp 类
  4. g_Fun()执行完后再析构掉XXX对象。

3.拷贝构造(深复制/浅复制)

  1. 程序存在 默认的拷贝函数 但是只能进行 浅复制

  2. 如果对象 存在 动态分配的内存 , 浅复制就会出现问题

    例:

    class Rect
    {
    public:
        Rect()      // 构造函数,p指向堆中分配的一空间
        {
            p = new int(100);
        }
        ~Rect()     // 析构函数,释放动态分配的空间
        {
            if(p != NULL)
            {
                delete p;
            }
        }
    private:
        int width;
        int height;
        int *p;     // 一指针成员
    };
    
    int main()
    {
        Rect rect1;
        Rect rect2(rect1);   // 复制对象
        return 0;
    }
    

    这个时候 对象 rect1 和 rect2 的 rect1.p 和 rect2.p 指向同一块New 出来的内存 。程序结束时会调用 析构函数 delete 动态分配的 内存 但是 rect1.p 和 rect2.p 指向同一块内存 从而会出现 double free 的保存 导致程序报错。

  3. 所以 这个时候 必须要用到 深复制 所谓深复制 就是在 拷贝构造函数中 加一句 new 来产生对应的 动态分配的 地址

    class Rect
    {
    public:
        Rect()      // 构造函数,p指向堆中分配的一空间
        {
            p = new int(100);
        }
        Rect(const Rect& r)
        {
            width = r.width;
            height = r.height;
            p = new int;    // 为新对象重新动态分配空间
            *p = *(r.p);
        }
        ~Rect()     // 析构函数,释放动态分配的空间
        {
            if(p != NULL)
            {
                delete p;
            }
        }
    private:
        int width;
        int height;
        int *p;     // 一指针成员
    };
    

    从而实现 拷贝构造函数

  4. 在代码中 可以在 Private 声明一个 私有拷贝构造函数。