[英]How to allocate memory with Constructor in deep copy?
我正在嘗試了解Deep Copy。 但是我只是對通過調用Constructor動態分配內存感到困惑 。
這是我成功完成的深層復制程序:
#include<iostream>
using namespace std;
class A{
public:
int *p;
A(){
p=new int;
}
void set(int b){
*p=b;
}
int get(){
return *p;
}
void operator=(const A &k){
p = new int;
*p=*(k.p);
}
~A(){
delete p;
}
};
int main()
{
A obj;
obj.set(3);
A obj1;
obj1=obj;
obj1.set(5);
cout << obj.get() << endl;
cout << obj1.get() << endl;
}
現在我只想問我創建了兩個對象,構造函數將調用兩次,並且在構造函數中動態分配內存。
那么我的問題是,指針應該指向兩個不同的動態內存位置(2個對象和2個指針),或者該指針與靜態數據成員相同(那么就不需要深度復制了)? 表示所有類對象的一個指針。
如果創建該類的兩個實例,則它們將具有兩個不同的p
成員,每個成員在內存中包含不同區域的不同地址,是的。
您可能可以判斷是否運行程序:它將顯示3和5,如果指針相同,則將顯示5兩次。
編輯:根據要求,進行一些補充說明(以及評論中所講內容的摘要)
首先,您的operator=
正在泄漏內存,相反,您應記住在重新分配內存之前先釋放已在p中分配的內存:
void operator=(const A &k){
delete p;
// as JoshuaGreen states in the comments, you can set p to nullptr
// here, that way, if new fails and throws, p will be set to nullptr
// and you'll know it doesn't contain anything (you'll have to test
// it in other methods to benefit from this modification though,
// but it will be safer)
p = nullptr;
p = new int;
*p=*(k.p);
}
盡管在這種特定情況下,您可以避免重新分配:
void operator=(const A &k){
// p = new int; // not needed
*p=*(k.p);
}
現在,重載賦值operator=
確實很重要(而您實際上忘記了重載副本構造函數),讓我們看看如果未定義此賦值operator=
會發生什么。
您的課程看起來像這樣:
#include<iostream>
using namespace std;
class A{
public:
int *p;
A(){
p=new int;
}
void set(int b){
*p=b;
}
int get(){
return *p;
}
~A(){
delete p;
}
};
但是實際上,編譯器會為您生成一個隱式定義的默認副本構造函數和默認賦值operator =。 當然,您看不到它們的實現,但是它們的行為與定義該類的行為完全相同:
#include<iostream>
using namespace std;
class A{
public:
int *p;
A(){
p=new int;
}
A(const A& other) :
p(other.p) {} // ! we're copying the pointer instead of reallocating memory
void set(int b){
*p=b;
}
int get(){
return *p;
}
A& operator=(const A& other){
p = other.p; // same here!
}
~A(){
delete p;
}
};
當您上課時要處理動態分配的內存,那很不好。 讓我們來看看您的主系統會發生什么:
int main()
{
// allocate a new pointer to int, let's call it p
A obj;
// set the content of p to 3
obj.set(3);
// allocate a new pointer to int, let's call it p1
A obj1;
// /!\
// instead of copying the content of p to the content of p1, we're
// actually doing p1 = p here! we're leaking memory AND the two
// objects point on the same memory!
obj1=obj;
// set the content of p1 to 5, but p1 is now equal to p because of
// the bad assignment, so we're also setting p's content to 5
obj1.set(5);
// print the content of p (5)
cout << obj.get() << endl;
// print the content of p1 (5)
cout << obj1.get() << endl;
}
// delete the contents of p and p1 /!\ we're actually deleting the same
// allocated memory twice! that's bad
這就是為什么您必須重新定義“三者” (復制構造函數,復制分配運算符和析構函數)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.