2010-08-05 60 views
1

使用基類的私有成員,我想下面的編譯,但它並不:C++:在平等的測試

template <typename T> 
struct Odp 
{ 
public: 
    operator*() const 
    { 
     return m_p; 
    } 

    T* operator->() const 
    { 
     return m_p; 
    } 

    T** operator&() 
    { 
     return &m_p; 
    } 

private: 
     T* m_p; 

}; 

struct Ftw : public Odp<int> 
{ 
    bool operator==(const Ftw& rhs) 
    { 
     return m_p == rhs.m_p; // C2248 cannot access private member 
    } 
}; 

有什麼辦法,使這項工作?我無法修改Odp

+0

我認爲這是在代碼中的錯誤。運算符*()返回的類型未指定,並且返回語句與運算符 - >()中的相同。 – 2010-08-05 00:20:36

+0

我開始對Odp感到無聊。你似乎以不同的方式提出同樣的問題。基本答案似乎是 - 不要創建派生類。 – 2010-08-05 00:21:16

+0

@尼爾你是正確的1)我使用'Odp'作爲我選擇的隨機名稱和2)我在問類似的問題。問題是我不能改變這個基類,但我需要在它上定義'=='運算符,以便它可以在STL集合中使用。(或者,也許我錯誤地認爲是這個信念?) – 2010-08-05 04:40:34

回答

4

Odp過載operator*返回m_p。您可以調用操作上*thisrhs

struct Ftw : public Odp<int> 
{ 
    bool operator==(const Ftw& rhs) const 
    { 
     return **this == *rhs; 
    } 
}; 

operator*超載是有點不尋常,但是:它可能應該返回*m_p代替,因爲operator->回報m_p(這將導致你的類具有一致性類指針語義)。如果你這樣做,你將不得不做到以下幾點來做比較:

return &**this == &*rhs; // or explicitly as: 
return &this->operator*() == &rhs.operator*(); 

這是有點亂,如果一元&超載爲T它不一定會工作(但是,你真的,真的不應該這樣做......)。您也可以通過顯式調用operator->獲得的指針,這可能是最好:

return this->operator->() == rhs.operator->(); 

真正的問題是,「這是什麼Odp,爲什麼要使用它,你爲什麼不能修改嗎?」


在一個不相關的音符,你operator==要麼被實現爲const成員函數或最好,如友元函數:

bool operator==(const Ftw& rhs) const { /* ... */ } 
friend bool operator==(const Ftw& lhs, const Ftw& rhs) { /* ... */ } 

在另一個不相關的音符,超載一元&幾乎是當然是一個壞主意。

+0

我想我會在這裏明確地調用'operator *'。 'return this-> operator *()== rhs.operator *();' – 2010-08-05 00:22:40

+0

@Ben:出於好奇,在這種情況下,您是否更喜歡明確的'operator'語法?我通常儘可能避免明確地調用操作符,因爲它似乎能夠抵消操作符重載的目的(當然,考慮到這個問題的要求,這是合理的)。我認爲我唯一一次明確地在生產代碼中調用操作符的時候,是當我做出了一個有趣的設計決定(閱讀:被大肆渲染)並創建了一個'operator []'模板後,才意識到它只能被調用明確地說:-O。 – 2010-08-05 00:37:15

+0

我猜是因爲代碼的意圖不是*通過智能指針*使用對象,它是*從智能指針*中檢索指針地址。不過,也許這個推理只適用於'operator->'。 – 2010-08-05 03:26:29

0

編譯器告訴你m_p是私有的。如果你想訪問派生類中的m_p,你需要將它設置爲protected或public。

+1

......或者使用現有的公共接口,它似乎總共提供了3種不同的方式來訪問'm_p'! – UncleBens 2010-08-05 00:39:12

+0

我的答案符合我認爲是作者的意圖。他特別詢問如何獲得他寫的工作。爲了實施他所寫的經營者,他必須使該成員受到保護或公開。 – nathan 2010-08-05 00:46:58

0

如果您無法修改Odp,則可以明確地呼叫operator->()。它返回你需要的內容並且應該被內聯。

+0

@Rosarch Thx編輯,但你在這句話中錯過了另外兩個「你」的例子。如果將「你」中的第一個字母大寫(因爲某些原因,我一直保持一致,但可能因爲我不知道的原因而不合適),這很煩人,請告訴我。我會停下來。 – 2010-08-05 00:32:09

+0

是的,也許我應該更一致。我看到了那個,認爲它是一個錯字(因爲大寫你通常意味着你指的是一個神),然後修正它。然後我看到你的使用情況一致,並由於某種原因決定不修復其餘部分。我想如果我要去糾正別人,我可能會更加認真對待它。 – 2010-08-05 00:37:02

0

由於Odp是給指針出在它的方法免費的(它甚至地址,OMG!這就像做門與許多鎖,然後給鍵周圍的每一個賊),你可以做

bool operator==(const Ftw& rhs) 
{ 
    return **this == *rhs; 
} 

只好Odp實現自己的比較操作,您可以使用這樣的:

bool operator==(const Ftw& rhs) 
{ 
    return Odp<int>::operator==(rhs) && ... other conditions ...; 
}