[英]Returning an object with a pointer member variable in C++
因此,我有一個upDate對象,該對象的指針成員變量僅指向默認值為1959年5月11日的數組:
upDate::upDate()
{ dptr = new int[3];
dptr[0] = 5;
dptr[1] = 11;
dptr[2] = 1959;
}
現在在我的主目錄中,我應該覆蓋+運算符。
upDate D1(5,9,1994);
upDate D2 = D1+1;//supposed to add 1 more day to the upDate.
但是當我輸出D2時,沒有我5/10/1994。 它給了我一個非常大的負數:-572662307 / -572662307 / -572662307。
這是我的operator +方法:
upDate upDate::operator+(int integer){
upDate temp;
int m = dptr[0];
//cout << m << endl;
int d = dptr[1];
int y = dptr[2];
int julian = convertToJulian(y, m, d);
julian += integer;
//cout << julian << endl;
temp.convertToGregorian(julian);
//cout << temp.getMonth() << " " << temp.getDay() << " " << temp.getYear() << endl;
return temp;
}
該方法中的所有提示都由我測試,以查看是否正確,而且是正確的。 因此,我認為這些都不正確。 但是,當我返回溫度時,我認為在將溫度返回為D2的過程中會丟失一些東西。 也許這是一個指針問題? 我不太確定
編輯:這是我的運算子=:
upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
copy.dptr[i] = dptr[i];
return copy;
}
和我的析構函數:
upDate::~upDate()
{
delete []dptr;
}
我想我從來沒有做過復制構造函數...但是我對如何制作它感到困惑?
也許這是一個指針問題?
大概。 在您的更新中,您說“我想我從來沒有做過復制構造函數”,這意味着該類違反了三則規則並且具有無效的復制語義。 復制后(就像從您發布的函數中返回時一樣),兩個副本都包含指向同一數組的指針。 大概兩個對象都有一個析構函數,該析構函數刪除了數組,而另一個對象的指針則懸空了。
我想我從來沒有做過復制構造函數...但是我對如何制作它感到困惑?
最好的方法不是。 停止使用new
和手動處理的指針,並從可正確復制的對象構建類; 在這種情況下,請將dptr
替換為數組或三個命名變量。 (如果您需要一個動態大小的數組,而您不在這里,那么std::vector
將是理想的)。
我可能會通過僅存儲儒略日來進一步簡化它,並且僅在必要時轉換為公歷,以便於人類可讀的演示。
如果您確實需要通過蒸汽管理內存,則需要一個析構函數
~upDate() {delete [] dptr;}
復制構造函數
upDate(upDate const & other) : dptr(new int[3]) {
std::copy(other.dptr, other.dptr+3, dptr);
}
和一個副本分配運算符。 它應該修改被調用的對象,而不是其參數(當然也不能像您一樣修改其參數的本地副本),並且通常應返回對已分配對象的引用,而不是其副本。
upDate & operator=(upDate const & other) {
std::copy(other.dptr, other.dptr+3, dptr);
return *this;
}
在C ++ 11中,出於效率考慮,您可能還需要考慮移動語義。
upDate(upDate && other) : dptr(other.dptr) {
other.dptr = nullptr;
}
upDate & operator=(upDate && other) {
if (this != &other) { // Careful: self-assignment can be tricky
dptr = other.dptr;
other.dptr = nullptr;
}
}
免責聲明:該代碼是在沒有編譯器和測試框架的幫助下編寫的,因此可能包含錯誤。 未經測試請勿使用。
tl; dr內存管理很困難。 除非確實需要,否則不要這樣做。 您不需要在這里。
您的operator=
函數向后工作。
//This version tries to make a=b work as though it were b=a
upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
copy.dptr[i] = dptr[i];
return copy;
}
也就是說,從我看到的示例來看 , operator=
應該將參數的值復制到當前對象中,在此您可以將參數從當前對象復制到參數中。
//Corrected version (judging by linked article.)
upDate & upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
dptr[i] = copy.dptr[i];
return *this;
}
我想我從來沒有做過復制構造函數
不行 注意這條線upDate D2 = D1+1;
,它將調用復制構造函數而不是operator =,因為您沒有指定一個,它將調用編譯器生成的復制構造函數,該復制構造函數執行成員級復制,因此數據成員D2.dptr = temp.dptr
共享相同的地址。 temp
被銷毀后, D2.dptr
指向無效地址,因此它為您提供了垃圾值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.