2011-05-19 40 views
1

考慮下面的類:返回參照切​​片對象(超型)

class Coord 
{ 
public: 
    double _x, _y; 

    Coord(double x, double y) 
    { 
     _x = x; 
     _y = y; 
    } 
}; 

class NamedPoint : public Coord 
{ 
public: 
    int _id; 

    NamedPoint(int id, double x, double y) : 
     Coord(x,y), 
     _id(id) 
    { 
    } 
}; 

我想創建NamedPoint的成員函數 - 座標() - 該返回對應於類型座標的基準NamedPoint。

例如,我想是這樣的:

const Coord& NamedPoint::coord() 
{ 
    return ((Coord)*this); 
} 

但我得到一個關於臨時變量的警告,我不是瘋了。

當然,下面的工作:

Coord coord() 
{ 
    Coord c = *this; 
    return c; 
} 

但我寧願返回引用。

有誰知道這是否可能使用繼承類?

對不起,不解釋功能的重點。我爲Coord和NamedPoint以不同的方式重載==運算符。 Coord只會檢查{x,y},NamedPoint會檢查{id,x,y}。如果我忘記在此==測試之前將NamedPoint投射到Coord,我將使用錯誤的版本。

所以,當我意識到

(Coord)np1 == (Coord)np2 

會給我我想要的,我寧願使用類似

np1.coord() == np2.coord() 

我認爲這是作爲對正在發生的事情更清楚。

+0

你似乎沒有注意到/承認轉換爲'Coord'的區別,它複製了對象的一部分,轉換爲'Coord&',它創建了對你的點的基類子對象的引用。 GMan的解決方案完成後者,你寫的所有代碼都會替代前者,這就是爲什麼你在第一個'coord()'函數中得到警告的原因。你說「我寧願返回一個參考」,但是你返回了一個(部分)副本的引用,而不是原始的。然後'(Coord)np1 ==(Coord)np2' comparies也複製。無論你做什麼,複製都是不必要的。 – 2011-05-19 00:39:07

+0

對不起,如果我不清楚。事實上,不同之處在於我首先提出這個問題的原因。我正在尋找一種方法來獲得對基類子對象的引用(順便說一句,這很好 - )我唯一能提出的解決方案就是創建子對象的副本。 – jedwards 2011-05-19 00:48:23

+0

不知道爲什麼這是downvoted。 – GManNickG 2011-05-19 08:25:06

回答

7

該功能的要點是什麼? NamedPoint隱式轉換爲Coord反正:

void foo(Coord& c) 
{ 
    c._x = 5; 
} 

NamedCoord nc(0, 1, 2); 
foo(nc); // c references the Coord part of nc 

無論如何,你的函數應該簡單地使用這種轉換:

const Coord& NamedPoint::coord() 
{ 
    // Bad: takes the value of *this and slices off 
    // the derived bits, leaving a temporary Coord. 
    /* return ((Coord)*this); */ 

    // Good: takes the value of *this and refers 
    // to the base bits, no temporaries. 
    return *this; 

    // (Same as:) 
    /* return ((Coord&)*this); */ 
} 
+0

對不清楚這一點 - 它更像是一種「哲學」類型的東西 - 我相應地更新了我的問題。 – jedwards 2011-05-19 00:29:47

+0

謝謝 - 我不認爲我知道鑄造參考類型的語法(Coord&)。欣賞它。 – jedwards 2011-05-19 00:36:04

3

@GMan給出了主要的解決方案。

然而,這可能是有趣更詳細地說明這個問題:

const Coord& NamedPoint::coord() 
{ 
    return ((Coord)*this); 
} 

這是大致相同:

const Coord& NamedPoint::coord() 
{ 
    Coord c = *this; 
    return c; 
} 

這清楚地表明,你正在返回參考一個臨時的堆棧,這使得對它的引用無用,因此也是警告。

現在在提出的案例中,Coord是基類,因此我們有@Gman給出的簡單解決方案。

在一般情況下,原則是如果您想要參考something,最好確保something仍然存在。

+0

謝謝,我原以爲這是警告的意思。 – jedwards 2011-05-19 00:34:56