1

我正在尝试对 class 进行深层复制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;
}
4

5 回答 5

14

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){ 
} 
于 2012-08-02T17:26:29.640 回答
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;
    }
};

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

于 2012-08-02T17:46:36.677 回答
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这里使用。
于 2012-08-02T17:29:40.780 回答
0

在这里,您不是在复制 b2

B *b3(b2);

相反,您将 b3 指向 b2

你应该有

B *b3 = new B(*b2);
于 2012-08-02T17:33:07.077 回答
-7

C++ 中没有浅/深拷贝之类的东西。您要么拥有被复制的值或指针/引用,要么完全定义了复制操作的语义。

于 2012-08-02T17:32:05.930 回答