2015-11-01 74 views
2

我有以下錯誤:
智能感知:返回類型與重寫虛擬函數的返回類型「計數器」不相同也不協變。「Counter :: operator ++」返回類型與返回類型(運算符++)不一致或不一致

這裏是我的項目的頭。
counter.h

/* Header file of Counter Class*/ 
#pragma once 
#include <iostream> 
using namespace std; 
//Class definition 
class Counter { 
    friend ostream &operator<<(ostream &out, const Counter &c); 
    public: 
     Counter(int n0 = 0); 
     virtual Counter &operator++(); 
     virtual Counter operator++(int); 
     void reset(); 
     int getCount() const; 

    private: 
     int count; 
}; 

LimitedCounter.h

#pragma once 
#include "counter.h" 

class LimitedCounter : public Counter{ 
    friend ostream &operator<<(ostream &out, const LimitedCounter &c); 
public: 
    LimitedCounter(int low, int up); 
    void reset(); 
    LimitedCounter& operator++(); 
    LimitedCounter operator++(int); // error here 
    operator int() { return getCount(); }; 
    int getCount() const { return Counter::getCount(); }; 
private: 
    int upper; 

}; 

和實現
counter.cpp

/* Implementation of Counter Class*/ 

#include "counter.h" 
#include <iostream> 

Counter:: Counter(int n0) { 
    count = n0; 
} 
Counter& Counter::operator++() { 
    count++; 
    return *this; 
} 
Counter Counter::operator++(int) { 
    Counter old = *this;; 
    count++; 
    return old; 
} 
void Counter::reset(){ 
    count = 0; 
} 
int Counter::getCount() const{ 
    return count; 
} 
ostream &operator<<(ostream & out, const Counter &c) { 
    out << "\nCounter value is now " << c.count ; 
    return out; 
} 

LimitedCounter.cpp

#include "LimitedCounter.h" 
LimitedCounter::LimitedCounter(int low, int up) : Counter(low), upper(up) {} 

LimitedCounter& LimitedCounter::operator++() { 
    if (getCount() < upper) { 
     Counter::operator++(); 
    } 
    return *this; 
} 

LimitedCounter LimitedCounter::operator++(int) { 
    if (getCount() < upper) { 
     LimitedCounter old = *this; 
     Counter::operator++(0); // question? 
     return old; 
    } 
    else { 
     return *this; 
    } 
} 

void LimitedCounter::reset() { 
    Counter::reset(); 
} 

//friend function 
ostream &operator<<(ostream &out, const LimitedCounter &c) { 
    out << c.getCount() << endl; 
    return out; 
} 

我得到的錯誤:
錯誤C2555: 'LimitedCounter ::運算++':重寫虛函數返回類型不同,不從協變 '反::運算++'

當我在counter.h後遞增刪除虛擬那麼有沒有錯誤可言。所以一切工作正常預增量。所以我不知道是不是因爲我如何實現後遞增?而且,當我重寫後遞增(操作++(INT)),是不是我寫的是這樣的:

Counter::operator++(0); 

謝謝你幫助我。

+1

多態性不與某些事情拌勻。如果您在指向「LimitedCounter」對象的「Counter」引用上調用「op ++」,那麼調用者代碼如何知道需要預留多少空間?有足夠的'Counter'對象,還是什麼? –

+0

這是一個並不真實的實現細節 - 如果編譯器真的想要,它可以很容易地透明間接。真正的問題是它是一個計數器值,因此不能是有限計數器或任何其他東西,除了計數器。 – Puppy

回答

4

的問題很簡單:你是返回由值的對象,所以你有以下的情況現在

virtual Counter Counter::operator++(int) 
LimitedCounter LimitedCounter::operator++(int) override 

,因爲該方法是virtual,正確的實現在運行時根據的虛函數表選擇你正在調用它的對象。

這意味着編譯器不能先驗地知道operator++返回的類型,但是由於它是一個值(而不僅僅是指針),所以他至少需要知道它的大小。

事實上,如果你有以下情況將被接受:

virtual Counter* Counter::operator++(int) 
LimitedCounter* LimitedCounter::operator++(int) override 

因爲運行時實現在任何情況下返回一個指針,以便編譯器將能夠正確地應對它。

該標準規定所允許,並認爲在10.3節協變(C++ 11):

壓倒一切的函數的返回類型應是相同的被覆蓋的函數或協變與類的返回類型的功能。如果函數D::f覆蓋了一個功能B::f,返回類型的功能是協變,如果它們滿足以下條件:

  • 兩者都是類型指針,兩者都是對類左值的引用,或兩者均爲rvalue引用到類

  • B::f返回類型的類是相同的類中的D::f返回類型的類,或者是一個明確的和可訪問的直接或間接的基類的類中的D::f返回類型

  • 指針或引用都具有相同的cv資格,並且返回類型D :: f中的類類型具有與返回類型B中的類類型相同的cv資格或更少的cv資格::F。

+0

嗨,我試着改變它,就像你建議的那樣。 'Counter * Counter :: operator ++(int){Counter old = * this; count ++; return &old;}。並且在限制計數器中。我執行'LimitedCounter lc(3,5); cout << counterA ++ << endl;'。它不打印3而是計數器的地址。對不起,我的愚蠢問題。 –

0

這是一些不同的方法來解決這樣的

  1. 問題時只需把所有的東西在一個類中。你真的需要2個計數器類中的一個可以與反戰略的參數進行調整,而不是(也可以從簡單的enum到一些複雜的類)

    enum class CountinngStretegy { Unlimited, Limited} 
    class Counter { 
    public: 
        Counter(CountinngStretegy strategy); 
        //... 
    } 
    
  2. Counter獨立LimitedCounter。然後,如果你想參數化的計數器類型,使用模板爲:

    template <typename SomeCounter> void do_smth_with_counter(SomeCounter counter); 
    
+0

嗨,因爲我必須在這種情況下使用2個不同的計數器(僅用於練習)。但謝謝你的建議。 –