如何在c ++中进行深层复制

时间:2012-08-02 17:24:27

标签: c++

我正在尝试对类B进行深层复制,但A未设置。

为什么b3->print会返回垃圾号而不是1

据我所知,b2和b3都指向同一个A对象。但是我用B的拷贝构造函数在堆上创建了一个新对象。那么他们为什么还在同一个对象上呢?

我希望这是有道理的。

#include <cstdlib>
#include <iostream>

using namespace std;

class A{
      int num;
public:
       A(int n):num(n){ cout<< "A "<< num << " constructor" <<endl;}  
       ~A(){ cout<< "A "<< num <<" destructor. " <<endl; }   

       int print(){
        cout<< num<< endl;
       }
};

class B{
      A *a;
      int num;
public:
       B(int n):num(n){
           a = new A(n);
           cout<< "B "<< num <<" constructor" <<endl;    
       }  
       ~B(){
            delete a; 
            cout<< "B "<< num <<" destructor"<<endl; 
       }    
       // Copy contructor
       B(const B & b): a(new A(b.num)){ 
       } 

       <strike>int<\strike> void print(){
        cout<< num << endl;
       }

       int get_num(){
           return num;
       }
};

int main(int argc, char *argv[])
{ 
    B *b2 = new B(1);
    B *b3(b2);
    b2->print();
    delete b2;
    b3->print();
    system("PAUSE");
    return EXIT_SUCCESS;
}

5 个答案:

答案 0 :(得分:11)

B *b3(b2);没有按你的想法行事。

相当于B* b3 = b2。指针将指向相同的位置。执行delete b2;时,您还可以释放b3指向的内存。

要进行深层复制,请执行以下操作:

 B* b3 = new B(*b2);

此处还有未定义的行为:

int print(){
   cout<< num << endl;
}

因为你永远不会回来。将返回类型更改为void

获得预期的价值:

B(const B & b): a(new A(b.num)), num(b.num){ 
} 

答案 1 :(得分:1)

这个问题的其他答案将解释指针是如何工作的,但你也应该明白,不使用指针是一个更好的解决方案。 C ++的默认行为适用于值语义。如果按值保存对象,则默认复制ctor和赋值运算符将执行“深层复制”。

class B{
    A a;
    int num;
public:
    B(int n): a(n), num(n){
        cout<< "B "<< num <<" constructor" <<endl;    
    }    

    void print(){
        cout<< num << endl;
    }

    int get_num(){
        return num;
    }
};

此外,如果你使用拥有指针,你通常应该使用智能指针。

答案 2 :(得分:0)

我想你可能打算写这样的东西:

#include <iostream>

class A
{
public:
    A(int n) : num_(n) {}

    void print() { std::cout << num() << std::endl; }

    int num() const { return num_; }

private:
    int num_;
};

class B
{
public:
    B(int n) : a(n) {}

    int num() const { return a.num(); }

private:
    A a;
};

int main()
{
    B b(1);
    B b2 = b; // deep copy
}

如你所见:

  1. B没有自己的num_成员。应避免重复。
  2. 无需实现复制构造函数或赋值运算符(三阶规则)。
  3. 此处不需要使用new

答案 3 :(得分:0)

这里你没有复制b2

B *b3(b2);

而你正在使b3指向b2

你应该

B *b3 = new B(*b2);

答案 4 :(得分:-6)

在c ++中没有浅/深拷贝这样的东西。您要么具有要复制的值或指针/引用,要么完全定义复制操作的语义。