简体   繁体   English

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

[英]Return type is not identical to nor covariant with return type (operator++)

I have the following error: 我有以下错误:
IntelliSense: return type is not identical to nor covariant with return type "Counter" of overridden virtual function "Counter::operator++" IntelliSense:返回类型与重写虚函数“Counter :: operator ++”的返回类型“Counter”不相同或协变

Here are the headers of my project. 这是我的项目的标题。
counter.h 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 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;

};

And the implementation 并实施
counter.cpp 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 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;
}

I get the error: 我收到错误:
error C2555: 'LimitedCounter::operator ++': overriding virtual function return type differs and is not covariant from 'Counter::operator ++' 错误C2555:'LimitedCounter :: operator ++':覆盖虚函数返回类型不同,并且不是'Counter :: operator ++'的协变

When I remove virtual in the post-increment of counter.h then there is no error at all. 当我在counter.h后递增中删除virtual时 ,则根本没有错误。 So everything works fine with the pre-increment . 因此, 预增量一切正常。 So I don't know is it because how I implement the post-increment ? 所以我不知道是因为我如何实现后增量 And also when I override the post-increment ( operator++(int) ), is it right that I write like this: 而且当我覆盖后增量( operator ++(int) )时,我是这样写的:

Counter::operator++(0);

Thanks for helping me. 谢谢你的帮助。

The problem is simple: you are returning an object by value, so you have the following situation 问题很简单:您按值返回对象,因此您有以下情况

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

Now, since the method is virtual , the correct implementation is chosen at runtime according to the vtable of the object you are calling it on. 现在,由于该方法是virtual ,因此根据您调用它的对象的vtable在运行时选择正确的实现。

This means that the compiler can't know a priori the type returned by operator++ but he needs to know at least its size since it's a value (and not just a pointer). 这意味着编译器不能事先知道operator++返回的类型,但是他需要至少知道它的大小,因为它是一个值(而不仅仅是一个指针)。

Indeed if you had the following situation would be accepted: 确实如果您有以下情况将被接受:

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

because the runtime implementation would in any case return a pointer so the compiler would be able to cope with it correctly. 因为运行时实现在任何情况下都会返回一个指针,因此编译器能够正确处理它。

The standard specifies what's allowed and considered covariant in §10.3 (C++11): 该标准规定了§10.3(C ++ 11)中允许和考虑的协变量:

The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. 重写函数的返回类型应与重写函数的返回类型相同,或者与函数类的协变相同。 If a function D::f overrides a function B::f , the return types of the functions are covariant if they satisfy the following criteria: 如果函数D::f覆盖函数B::f ,则函数的返回类型如果满足以下条件则是协变的:

  • both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes 两者都是类的指针,都是对类的左值引用,或者两者都是对类的右值引用

  • the class in the return type of B::f is the same class as the class in the return type of D::f , or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f 在返回类型的类B::f是相同的类中的返回类型的类D::f ,或者是一个明确的和可访问的直接或间接的基类中的返回类型的类的D::f

  • both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f. 指针或引用具有相同的cv限定,并且返回类型D :: f中的类类型具有与B :: f的返回类型中的类类型相同的cv-qualification或更少的cv-qualification。

It is some different ways to solve problem like this 这是解决这类问题的一些不同方法

  1. Just keep all things in one class. 把所有的东西放在一个班级里。 Do you really need 2 counter class instead of one that can be parametrized with counter strategy (that can be from simple enum to some complicated class ) 你真的需要2个计数器类而不是一个可以用计数器策略进行参数化的计数器(可以从简单的enum到一些复杂的类)

     enum class CountinngStretegy { Unlimited, Limited} class Counter { public: Counter(CountinngStretegy strategy); //... } 
  2. Make Counter independent from LimitedCounter . 使Counter独立于LimitedCounter Then if you want parametrize on counter type, use templates for that: 然后,如果您想在计数器类型上进行参数化,请使用以下模板:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM