簡體   English   中英

在C ++中使用指針成員變量返回對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM