C++ 拷贝构造函数

C++ 拷贝构造函数

拷贝构造函数是一个 重载 的构造函数,用于从另一个对象声明和初始化一个对象。

拷贝构造函数有两种类型

  • 默认拷贝构造函数: 编译器定义了默认的拷贝构造函数。如果用户没有定义拷贝构造函数,编译器会提供默认的构造函数。
  • 用户自定义构造函数: 程序员定义了用户自定义的构造函数。

C++ 拷贝构造函数

用户自定义复制构造函数的语法

Class_name(const class_name &old_object);

考虑以下情况:

class A
{
    A(A &x) //  copy constructor.
   {
       // copyconstructor.
   }
} 

在上述情况下,

可以通过以下方式调用复制构造函数:

C++ 拷贝构造函数

让我们看一个拷贝构造函数的简单示例。

// 拷贝构造函数的程序。

#include <iostream>
using namespace std;
class A
{
   public:
    int x;
    A(int a)                // parameterized constructor.
    {
      x=a;
    }
    A(A &i)               // copy constructor
    {
        x = i.x;
    }
};
int main()
{
  A a1(20);               // Calling the parameterized constructor.
 A a2(a1);                //  Calling the copy constructor.
 cout<<a2.x;
  return 0;
}

输出:

20

当调用复制构造函数时

复制构造函数在以下情况下被调用:

  • 当我们用同一类别的另一个现有对象初始化对象时。例如,Student s1 = s2,其中Student是类别。
  • 当同一类别的对象以按值方式作为参数传递时。
  • 当函数通过按值方式返回同一类别的对象时。

构造函数产生两种类型的拷贝

  • 浅拷贝
  • 深拷贝

浅拷贝

  • 默认的复制构造函数只能产生浅拷贝。
  • 浅拷贝被定义为通过复制所有成员变量的数据来创建对象的过程。

让我们通过一个简单的例子来理解:

#include <iostream>

using namespace std;

class Demo
{
    int a;
    int b;
    int *p;
    public:
    Demo()
    {
        p=new int;
    }
    void setdata(int x,int y,int z)
    {
        a=x;
        b=y;
        *p=z;
    }
    void showdata()
    {
        std::cout << "value of a is : " <<a<< std::endl;
        std::cout << "value of b is : " <<b<< std::endl;
        std::cout << "value of *p is : " <<*p<< std::endl;
    }
};
int main()
{
  Demo d1;
  d1.setdata(4,5,7);
  Demo d2 = d1;
  d2.showdata();
    return 0;
}

输出:

value of a is : 4   
value of b is : 5  
value of *p is : 7 

C++ 拷贝构造函数

在上述情况下,程序员没有定义任何构造函数,因此,语句 Demo d2 = d1; 调用了编译器定义的默认构造函数。默认构造函数创建了现有对象的精确副本或浅拷贝。因此,两个对象的指针p都指向相同的内存位置。因此,当一个字段的内存被释放时,另一个字段的内存也会自动被释放,因为两个字段都指向同一个内存位置。这个问题通过 用户定义的构造函数 来解决,该构造函数创建了 深拷贝

深拷贝

深拷贝动态分配了副本的内存,然后复制了实际值,源对象和副本都有不同的内存位置。这样,源对象和副本是不同的,不会共享同一内存位置。深拷贝要求我们编写用户定义的构造函数。

让我们通过一个简单的例子来理解。

#include <iostream>
using namespace std;
class Demo
{
    public:
    int a;
    int b;
    int *p;

    Demo()
    {
        p=new int;
    }
    Demo(Demo &d)
    {
        a = d.a;
        b = d.b;
        p = new int;
        *p = *(d.p);
    }
    void setdata(int x,int y,int z)
    {
        a=x;
        b=y;
        *p=z;
    }
    void showdata()
    {
        std::cout << "value of a is : " <<a<< std::endl;
        std::cout << "value of b is : " <<b<< std::endl;
        std::cout << "value of *p is : " <<*p<< std::endl;
    }
};
int main()
{
  Demo d1;
  d1.setdata(4,5,7);
  Demo d2 = d1;
  d2.showdata();
  return 0;
}

输出:

value of a is : 4   
value of b is : 5   
value of *p is : 7   

C++ 拷贝构造函数

复制构造函数和赋值操作符(=)的区别

复制构造函数 赋值运算符
这是一个重载的构造函数。 这是一个位运算符。
它使用已有对象初始化新对象。 它将一个对象的值赋给另一个对象。
复制构造函数的语法: Class_name(const class_name &object_name) { // 构造函数的内容 } 赋值运算符的语法: Class_name a,b; b = a;
复制构造函数 在用已有对象初始化新对象时被调用。
对象作为参数传递给函数。
它返回对象。
赋值运算符 在将已有对象赋给新对象时被调用。
现有对象和新对象共享不同的内存位置。 现有对象和新对象共享相同的内存位置。
如果程序员没有定义复制构造函数,编译器将自动生成隐式的默认复制构造函数。 如果我们没有重载“=”运算符,将发生位复制。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程