简体   繁体   English

C++ 深浅拷贝

[英]C++ Deep and Shallow Copy

I need to include shallow copy constructor and I'm completely lost.我需要包含浅拷贝构造函数,我完全迷失了。 I thought that the compiler provided a default shallow copy constructor but I have to provide one as well but I'm not sure how to write it.我认为编译器提供了一个默认的浅拷贝构造函数,但我也必须提供一个,但我不确定如何编写它。 I tried writing it similar to the WrapArrayDeep copy constructor without the pointers but that didn't work.我尝试编写它类似于 WrapArrayDeep 复制构造函数,但没有指针,但没有奏效。 After altering the array both arrays for WrapArrayShallow should be empty.更改数组后,WrapArrayShallow 的 arrays 都应该为空。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#pragma warning(disable: 4996)
using namespace std;

class WrapArrayDeep
{

    public:
        WrapArrayDeep() 
        {
            capacity = 5;
            pca = new char[capacity];
            
            for(int i = 0;i < capacity;i++)
                *(pca+i) = (97+i);
        } //ends default constructor
        
        WrapArrayDeep(const WrapArrayDeep& wad) //deep copy
        {
            capacity = wad.getCapacity();
            pca = new char[capacity];
            
            for (int i = 0;i < capacity;i++)
                *(pca+i) = wad.pca[i];
        } //ends copy constructor
        
        ~WrapArrayDeep()
        {
            cout << "destructor for WrapArrayDeep!\n";
            delete [] pca;
            
        } //ends destructor
        
        void printArr()
        {
            for(int i = 0;i < capacity;i++)
                cout << pca[i] << " ";
            
            cout << endl;
        } //ends print
        
        void alterArr()
        {
            for(int i = 0;i < capacity;i++)
                *(pca + i) = (123+i);
        }
    
        int getCapacity() const
        {
            return capacity;
        }
    
        WrapArrayDeep& operator =(const WrapArrayDeep& wad)
        {
            if(capacity != wad.capacity)
            {
                delete [] pca;
                pca = new char[wad.capacity];
            }
            
            capacity = wad.capacity;
            for(int i =0;i < capacity;i++)
                pca[i] = wad.pca[i];
                
            return *this;
        } //end of = operator overload
        
    private:
        int capacity;
        char *pca;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

class WrapArrayShallow
{
    public:
        WrapArrayShallow()
        {
            capacity = 5;
            pca = new char[capacity];
            for(int i = 0;i < capacity;i++)
                pca[i] = (97+i);
        } //ends default constructor
        
        ~WrapArrayShallow()
        {
            cout << "destructor for WrapArrayShallow!\n";
            delete [] pca;
        } //ends destructor
        
        void printArr()
        {
            for(int i = 0;i < capacity;i++)
                cout << *(pca + i) << " ";
        }
        
        void alterArr()
        {
            for(int i = 0;i < capacity;i++)
                pca[i] = (123 + i);
        }
        
        int getCapacity() const
        {
            return capacity;
        }
        
    private:
        int capacity;
        char *pca;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
 int main()
 {
    //~~~~~~~~Part 1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
      cout << "Part 1\n";
     int i = 7;
     int *pi;
     pi = &i;
     
     cout << "i = " << i << endl << "pi = " << pi << endl << "*pi = " << *pi << endl;
     
     cout << "address of i = " << &i << endl << "address of pi = " << &pi << endl;
     
     int **ppi;
     ppi = &pi;
     
     cout << "ppi = " << ppi << endl << "*ppi = " << *ppi << endl;
     
     cout << "address of ppi = " << &ppi << endl << "**ppi = " <<**ppi <<endl;
     cout << endl << "~~~~~~~~~~~~~~~~~~~~~~~~~~~";

    //~~~~~~~~Part 2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    cout << "\nPart 2\n";
    cout << "This section instantiates a wrapper class for a dynamic array of 5 elements. \n";
    
    WrapArrayDeep wad1, *wad2;
    cout <<"WrapArray Deep 1\n";
    wad1.printArr();
    
    //deep copy of wad1
    wad2 = new WrapArrayDeep(wad1);
    cout << "WrapArrayDeep 2 ~ copy constructor \n";
    wad2->printArr();
     
    wad1.alterArr();
    cout << "after altering WrapArrayDeep1, 1 and 2 = \n";
    wad1.printArr();
    wad2->printArr();
     
    WrapArrayShallow was1, *was2;
    cout << "WrapArrayShallow1\n";
    was1.printArr();
     
    //shallow copy of was1
    was2 = new WrapArrayShallow(was1);
    cout << "\nWrapArrayShallow2\n";
    was2->printArr();
     
    was1.alterArr();
    cout << "\nafter altering WrapArrayShallow1, 1 and 2 = \n";
    was1.printArr();
    cout << endl;
    was2->printArr();
     
    cout << endl;

    delete wad2;
    delete was2;
    
    cout << endl;
    system("pause");
    return 0;
}

To describe at the surface, Deep copy manages every variables including dynamically allocated one and safely copy to the destination object while the shallow copy don't care much about the dynamic variables.从表面上看,深拷贝管理每个变量,包括动态分配的变量和安全拷贝到目标 object,而浅拷贝不太关心动态变量。 You might have a good read here你可能有一个很好的阅读here

When you copy a WrapArrayShallow , there are now two pointers pointing to the same array, and when either WrapArrayShallow is destroyed, you delete[] the array.当你复制WrapArrayShallow时,现在有两个指针指向同一个数组,当其中一个WrapArrayShallow被销毁时,你delete[]数组。

Your program exhibits undefined behaviour, it uses a pointer that has been invalidated, when the second WrapArrayShallow is destroyed, and you delete[] pca .您的程序表现出未定义的行为,它使用已失效的指针,当第二个WrapArrayShallow被销毁时,您delete[] pca

You need to co-ordinate between the different WrapArrayShallow objects such that the last survivor delete[] s the array when it is destroyed.您需要在不同的WrapArrayShallow对象之间进行协调,以便最后一个幸存者delete[]在销毁数组时成为该数组。 The simplest way is to use a std::shared_ptr<char[]> instead of a char *最简单的方法是使用std::shared_ptr<char[]>而不是char *

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM