2014-11-21 90 views
2

重載操作從抽象類如果我有一個抽象類,如下所示:使用在派生類

class Base{ 
public: 
    // some pure virtual functions 
    bool operator< (Base &other) const { return str < other.str; } 
private: 
    string str; 
}; 

如果派生類也比較就像基類(操作者小於功能將是相同的基類),是否有可能使用繼承或虛函數來實現這一點?

回答

3

你不需要’需要做特別的事情。操作員被繼承,就像任何其他成員函數:

#include <string> 
using namespace std; 

class Base 
{ 
private: 
    string str_; 

public: 
    auto operator<(Base const& other) const 
     -> bool 
    { return str_ < other.str_; } 
}; 

class Derived: public Base {}; 

auto main() -> int 
{ 
    Derived d1, d2; 
    d1 < d2; 
} 

順便指出,該運營商將不會被隱式轉換被要求Derived或一些左側的說法Base

這是二元運算符最好定義爲非成員的主要原因。

但是,還要注意,作爲非成員,如果左邊的形式參數是對非const的引用(例如operator<<),那麼它需要一個右值引用版本才能綁定到臨時實參,如果需要的話。


一個並不鮮見的方式來定義操作爲非成員,但行內,是使用friend機制,如下所示:

#include <string> 
using namespace std; 

class Base{ 
private: 
    string str_; 
public: 
    friend 
    auto operator<(Base const &a, Base const& b) 
     -> bool 
    { return (a.str_ < b.str_); } 
}; 

class Derived: public Base {}; 

struct Convertible { operator Base() const { return Base(); } }; 

auto main() -> int 
{ 
    Derived d1, d2; 
    d1 < d2; 

    Convertible conv; 
    conv < d2; 
} 

但是請注意,這種方法的操作只能通過參數依賴查找,ADL發現。

+0

這是我見過的最簡單的'main()')+1的答案雖然 – vsoftco 2014-11-21 22:18:55

+0

你能解釋一下你最後一個關於ADL的說法嗎? ADL在這裏開始了什麼? 'operator <(conv,d2)'只是通過它的'operator Base()'隱式轉換爲''Base''的''對象,但ADL在哪裏進場?哦,我明白了,你在'Base'中聲明瞭它,並且不會在全局範圍內找到... – vsoftco 2014-11-21 22:35:41

+0

@vsoftco:在'conv 2014-11-21 22:39:33

4

因爲名稱查找會在基類中找到operator<,所以不需要執行任何操作。
但是,將運營商定義爲非會員friend函數是可行的。即

friend bool operator< (Base const& lhs, Base const& rhs) 
{ 
    return lhs.str < rhs.str; 
} 

Demo

+0

這並不是說「一般」不需要做任何事情 - 人們不需要做任何事情(一般情況下「罷工」)。此外,它不是「可能是可行的」 - 將二進制運算符實現爲實際二進制函數是可行的(並且是優選的)。 – 2014-11-21 22:10:26

+0

@ PaulJ.Lucas我(通常)不喜歡固定的,絕對的陳述。 :O) – Columbo 2014-11-21 22:13:07

0

我想對伊斯特伍德先生的帖子發表一些評論/說明:)可能有意義:因爲操作員成員函數在派生類中與基類中的完全相同(即比較相同的數據成員),你可以直接使用它,而不是重寫。

您必須重寫的唯一成員函數是純虛函數。

實際上,由於此成員函數未標記爲virtual,因此您無法將其覆蓋。

希望能夠解決問題!