2015-11-01 120 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个不同的计数器(仅用于练习)。但谢谢你的建议。 –