C++中的浅复制与深复制

默认构造函数将作为参数传入的对象的每个成员变量复制到新对象的成员变量中,这被称为成员浅复制。这虽然对大多数成员变量可行,但对于指向自由存储区中对象的指针成员变量不可行。

成员浅复制只是将对象成员变量的值复制到另一个对象中,两个成员变量的指针最后指向同一个内存块,当其中任何一个指针被delete时,将生成一个迷途指针,程序将处于危险之中。如图:

假如旧对象指针成员变量所指堆内存被释放后,此时新对象指针成员变量仍指向该内存块,这是不合法的。这种情况的解决办法是:创建自己的复制构造函数并根据需要来分配内存。分配内存后,可以将原对象的值复制到新内存中。这称之为深层复制。

程序实例如下:

  1. #include <iostream>
  2. using namespace std;
  3. class Cat
  4. {
  5. public:
  6.   Cat();
  7.   Cat(const Cat &);
  8.   ~Cat();
  9.   int GetAge() const { return *itsAge; }
  10.   int GetWeight() const { return *itsWeight; }
  11.   void SetAge(int age) { *itsAge=age; }
  12. private:
  13.   int *itsAge;    //实际编程并不会这样做,
  14.   int *itsWeight; //我仅仅为了示范
  15. };
  16. Cat::Cat()
  17. {/*构造函数,在堆中分配内存*/
  18.   itsAge=new int;
  19.   itsWeight=new int;
  20.   *itsAge=5;
  21.   *itsWeight=9;
  22. }
  23. Cat::Cat(const Cat & rhs)
  24. {/*copy constructor,实现深层复制*/
  25.   itsAge=new int;
  26.   itsWeight=new int;
  27.   *itsAge=rhs.GetAge();
  28.   *itsWeight=rhs.GetWeight();
  29. }
  30. Cat::~Cat()
  31. {
  32.   delete itsAge;
  33.   itsAge=0;
  34.   delete itsWeight;
  35.   itsWeight=0;
  36. }
  37. int main()
  38. {
  39.   Cat Frisky;
  40.   cout << "Frisky's age: "<<Frisky.GetAge()<<endl;
  41.   cout << "Setting Frisky to 6.../n";
  42.   Frisky.SetAge(6);
  43.   cout << "Create Boots from Frisky/n";
  44.   Cat Boots=Frisky; //or Cat Boots(Frisky);
  45.   cout << "Frisky's age: " <<Frisky.GetAge()<<endl;
  46.   cout << "Boots' age : "<<Boots.GetAge()<<endl;
  47.   cout << "Set Frisky to 7.../n";
  48.   Frisky.SetAge(7);
  49.   cout << "Frisky's age: "<<Frisky.GetAge()<<endl;
  50.   cout << "Boots' age: "<<Boots.GetAge()<<endl;
  51.   return 0;
  52. }
  53. //输出:
  54. //Frisky's age: 5
  55. //Setting Frisky to 6...
  56. //Create Boots from Frisky
  57. //Frisky's age: 6
  58. //Boots' age : 6
  59. //Set Frisky to 7...
  60. //Frisky's age: 7
  61. //Boots' age: 6

 

设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。 设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值