如何在c++中进行深度复制
How do I do a deep copy in 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;
}
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){
}
这个问题的其他答案将解释指针是如何工作的,但您也应该明白,不使用指针是更好的解决方案。C++的默认行为与值语义配合得很好。如果按值保存对象,则默认的复制操作符和赋值操作符将执行"深度复制"。
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;
}
};
此外,如果你确实使用拥有指针,你通常应该使用智能指针。
这里您不是在复制b2
B *b3(b2);
相反,你正在使b3指向b2
你应该有
B *b3 = new B(*b2);
我想你可能打算写这样的东西:
#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
在c++中没有浅/深复制这样的东西。您有被复制的值或指针/引用,它们完全定义了复制操作的语义。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- C++尝试深度复制唯一指针时出现内存访问冲突
- 在 c++ 中使用深度复制的运算符重载
- 如何深度复制链表对象指针
- 我有两棵二叉树.我想在不更改输入树的情况下深度复制两个二叉树的结果
- 如何将结构深度复制到向量的每个元素
- 我需要做一个深度复制,我是否正确使用了我的复制构造函数?
- 是否可以在不显式迭代每个元素的情况下深度复制指针容器?
- 如何深度复制unique_ptr向量
- 二叉搜索树 深度复制和取消引用
- 链表的这个别名运算符是否会产生深度复制
- 有没有一种 stl 方法来执行指针向量的深度复制
- cv::P oint3f 赋值运算符是否执行"深度"复制?
- Qt:通过深度复制访问列表中的数据结构是否应该比通过指针访问它慢得多
- 深度复制包含引用成员(C++)的结构
- 如何将“char *”深度复制到std::stringstream
- 如何在双向链表上执行深度复制
- 在复制构造函数中执行深度复制
- 深度复制cv::垫子替代品,哪个更好?
- 在 C/C++ 中使用 ProtoBuf 进行深度复制