我正在尝试对类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;
}
答案 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
}
如你所见:
B
没有自己的num_
成员。应避免重复。new
。答案 3 :(得分:0)
这里你没有复制b2
B *b3(b2);
而你正在使b3指向b2
你应该B *b3 = new B(*b2);
答案 4 :(得分:-6)
在c ++中没有浅/深拷贝这样的东西。您要么具有要复制的值或指针/引用,要么完全定义复制操作的语义。