Return 类型与 return 类型不相同也不协变(operator++)
Return type is not identical to nor covariant with return type (operator++)
我有以下错误:
IntelliSense: return 类型与重写虚函数 [=58= 的 return 类型 "Counter" 不相同也不协变]
这是我项目的headers。
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::operator ++':重写虚函数 return 类型与 'Counter::operator ++'
不同且不协变
当我在 post-increment 中删除 virtual 时 counter.h 那么就完全没有错误了。因此,pre-increment 一切正常。所以我不知道是不是因为我如何实施 post-increment?而且当我覆盖 post-increment ( operator++(int) )时,我这样写对吗:
Counter::operator++(0);
谢谢你的帮助。
问题很简单:你return按值访问一个对象,所以你有以下情况
virtual Counter Counter::operator++(int)
LimitedCounter LimitedCounter::operator++(int) override
现在,由于该方法是 virtual
,因此在运行时根据您调用它的对象的 vtable 选择正确的实现。
这意味着编译器无法先验地知道 return 由 operator++
编辑的类型,但他至少需要知道它的大小,因为它是一个值(而不仅仅是一个指针) .
如果您有以下情况确实会被接受:
virtual Counter* Counter::operator++(int)
LimitedCounter* LimitedCounter::operator++(int) override
因为运行时实现在任何情况下都会 return 一个指针,因此编译器能够正确处理它。
该标准在 §10.3 (C++11) 中指定了允许的和被认为是协变的内容:
覆盖函数的 return 类型应与覆盖函数的 return 类型相同或与函数的 class 类型协变。如果一个函数 D::f
覆盖了一个函数 B::f
,那么函数的 return 类型是协变的,前提是它们满足以下条件:
都是指向classes的指针,都是对classes的左值引用,或者都是对classes的右值引用
return 类型中的 class B::f
与 return 中的 class 相同 class =] 类型 D::f
,或者是 return 类型 D::f
[=19= 中 class 的明确且可访问的直接或间接基础 class ]
两个指针或引用具有相同的 cv 限定,并且 D::f 的 return 类型中的 class 类型具有与 or 相同的 cv 限定在 B::f 的 return 类型中,cv 资格低于 class 类型。
解决这样的问题有一些不同的方法
把所有的东西都放在一个地方class。你真的需要 2 个计数器 class 而不是一个可以用计数器 策略 参数化的计数器吗(可以从简单的 enum
到一些复杂的 class )
enum class CountinngStretegy { Unlimited, Limited}
class Counter {
public:
Counter(CountinngStretegy strategy);
//...
}
使 Counter
独立于 LimitedCounter
。然后,如果您想对计数器类型进行参数化,请为此使用模板:
template <typename SomeCounter> void do_smth_with_counter(SomeCounter counter);
我有以下错误:
IntelliSense: return 类型与重写虚函数 [=58= 的 return 类型 "Counter" 不相同也不协变]
这是我项目的headers。
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::operator ++':重写虚函数 return 类型与 'Counter::operator ++'
当我在 post-increment 中删除 virtual 时 counter.h 那么就完全没有错误了。因此,pre-increment 一切正常。所以我不知道是不是因为我如何实施 post-increment?而且当我覆盖 post-increment ( operator++(int) )时,我这样写对吗:
Counter::operator++(0);
谢谢你的帮助。
问题很简单:你return按值访问一个对象,所以你有以下情况
virtual Counter Counter::operator++(int)
LimitedCounter LimitedCounter::operator++(int) override
现在,由于该方法是 virtual
,因此在运行时根据您调用它的对象的 vtable 选择正确的实现。
这意味着编译器无法先验地知道 return 由 operator++
编辑的类型,但他至少需要知道它的大小,因为它是一个值(而不仅仅是一个指针) .
如果您有以下情况确实会被接受:
virtual Counter* Counter::operator++(int)
LimitedCounter* LimitedCounter::operator++(int) override
因为运行时实现在任何情况下都会 return 一个指针,因此编译器能够正确处理它。
该标准在 §10.3 (C++11) 中指定了允许的和被认为是协变的内容:
覆盖函数的 return 类型应与覆盖函数的 return 类型相同或与函数的 class 类型协变。如果一个函数 D::f
覆盖了一个函数 B::f
,那么函数的 return 类型是协变的,前提是它们满足以下条件:
都是指向classes的指针,都是对classes的左值引用,或者都是对classes的右值引用
return 类型中的 class
B::f
与 return 中的 class 相同 class =] 类型D::f
,或者是 return 类型D::f
[=19= 中 class 的明确且可访问的直接或间接基础 class ]两个指针或引用具有相同的 cv 限定,并且 D::f 的 return 类型中的 class 类型具有与 or 相同的 cv 限定在 B::f 的 return 类型中,cv 资格低于 class 类型。
解决这样的问题有一些不同的方法
把所有的东西都放在一个地方class。你真的需要 2 个计数器 class 而不是一个可以用计数器 策略 参数化的计数器吗(可以从简单的
enum
到一些复杂的 class )enum class CountinngStretegy { Unlimited, Limited} class Counter { public: Counter(CountinngStretegy strategy); //... }
使
Counter
独立于LimitedCounter
。然后,如果您想对计数器类型进行参数化,请为此使用模板:template <typename SomeCounter> void do_smth_with_counter(SomeCounter counter);