返回类型与返回类型(操作符++)不相同或协变

Hen*_*ran 3 c++ polymorphism virtual inheritance operator-overloading

我有以下错误:
IntelliSense:返回类型与覆盖虚函数"Counter :: operator ++"的返回类型"Counter"不相同或协变

这是我的项目的标题.
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;
};
Run Code Online (Sandbox Code Playgroud)

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;

};
Run Code Online (Sandbox Code Playgroud)

并执行
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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

我得到错误:
错误C2555:'LimitedCounter :: operator ++':覆盖虚函数返回类型不同,并且不是'Counter :: operator ++'的协变

当我在counter.h后递增中删除virtual时,则根本没有错误.因此,预增量一切正常.所以我不知道是因为我如何实现后增量?而且当我覆盖后增量(operator ++(int))时,我是这样写的:

Counter::operator++(0);
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

Jac*_*ack 5

问题很简单:您按值返回对象,因此您有以下情况

virtual Counter Counter::operator++(int)
LimitedCounter LimitedCounter::operator++(int) override
Run Code Online (Sandbox Code Playgroud)

现在,由于方法是virtual,在运行时根据您调用它的对象的vtable选择正确的实现.

这意味着编译器不能事先知道返回的类型,operator++但是他需要至少知道它的大小,因为它是一个值(而不仅仅是一个指针).

确实如果您有以下情况将被接受:

virtual Counter* Counter::operator++(int)
LimitedCounter* LimitedCounter::operator++(int) override
Run Code Online (Sandbox Code Playgroud)

因为运行时实现在任何情况下都会返回一个指针,因此编译器能够正确处理它.

该标准规定了§10.3(C++ 11)中允许和考虑的协变量:

重写函数的返回类型应与重写函数的返回类型相同或与函数类的协变相同.如果函数D::f覆盖函数B::f,则函数的返回类型如果满足以下条件则是协变的:

  • 两者都是类的指针,都是对类的左值引用,或者两者都是对类的右值引用

  • 返回类型中的类与返回类型中B::f的类是同一个类D::f,或者是返回类型中类的明确且可访问的直接或间接基类D::f

  • 指针或引用具有相同的cv限定,并且返回类型D :: f中的类类型具有与B :: f的返回类型中的类类型相同的cv-qualification或更少的cv-qualification.