C++教程
C++控制语句
C++函数
C++数组
C++指针
C++对象
C++继承
C++多态
C++抽象
C++常用
C++ STL教程
C++迭代器
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

在以下情况下调用副本构造函数时

在以下情况下调用副本构造函数时:
当我们使用另一个具有相同类类型的现有对象初始化该对象时。例如,学生s1 = s2,其中学生是班级。 当同一类类型的对象通过值作为参数传递时。 当函数按值返回相同类类型的对象时。

构造函数会生成两种类型的副本:

浅拷贝 深层复制

浅拷贝

默认副本构造函数只能生成浅表副本。 浅表副本定义为通过按原样复制所有成员变量的数据来创建对象副本的过程。
让我们通过一个简单的示例了解这一点:
#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++副本构造函数
在上述情况下,程序员定义了自己的构造函数,因此语句Demo d2 = d1; 调用用户定义的副本构造函数。它创建值类型数据和指针p指向的对象的精确副本。深度复制不会创建引用类型变量的副本。

差异副本构造函数和赋值运算符(=)

副本构造器 分配运算符
这是一个重载的构造函数。 它是按位运算符。
它将使用现有对象初始化新对象。 它将一个对象的值分配给另一个对象。
副本构造函数的语法:
Class_name(const class_name&object_name)
{
//构造函数的主体。
}
赋值运算符的语法:
类名a,b;
b = a;
使用现有对象初始化新对象时,将调用副本构造函数。
该对象作为参数传递给函数。
它返回对象。
当我们将现有对象分配给新对象时,将调用赋值运算符。
现有对象和新对象都共享不同的内存位置。 现有对象和新对象都共享相同的内存位置。
如果程序员未定义副本构造函数,则编译器将自动生成隐式默认副本构造函数。 如果我们不重载" ="运算符,则将按位复制。

昵称: 邮箱:
Copyright © 2022 立地货 All Rights Reserved.
备案号:京ICP备14037608号-4