我有以下错误:
IntelliSense:返回类型与重写虚拟函数“Counter :: operator ++”的返回类型“Counter”不相同或不协变
以下是我项目的标题 的 counter.h
SSLContext context = SSLContext.getDefault();
SSLSocketFactory sf = context.getSocketFactory();
String[] cipherSuites = sf.getSupportedCipherSuites();
for (String cs : cipherSuites)
System.out.println(cs);
LimitedCounter.h
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS_DH_anon_WITH_AES_128_GCM_SHA256
TLS_DH_anon_WITH_AES_128_CBC_SHA256
TLS_ECDH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_WITH_NULL_SHA256
TLS_ECDHE_ECDSA_WITH_NULL_SHA
TLS_ECDHE_RSA_WITH_NULL_SHA
SSL_RSA_WITH_NULL_SHA
TLS_ECDH_ECDSA_WITH_NULL_SHA
TLS_ECDH_RSA_WITH_NULL_SHA
TLS_ECDH_anon_WITH_NULL_SHA
SSL_RSA_WITH_NULL_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
并实施
的 counter.cpp
/* 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.cpp
#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;
};
我收到错误:
错误C2555:'LimitedCounter :: operator ++':覆盖虚函数返回类型不同并且不是'Counter :: operator ++'的协变
当我删除 counter.h 的后增量中的虚拟时,根本没有错误。因此,预增量一切正常。所以我不知道是因为我如何实施后增量?而且当我覆盖后增量( operator ++(int))时,我是这样写的:
/* 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;
}
感谢您的帮助。
答案 0 :(得分:5)
问题很简单:您按值返回对象,因此您有以下情况
virtual Counter Counter::operator++(int)
LimitedCounter LimitedCounter::operator++(int) override
现在,由于方法是virtual
,因此在运行时根据您调用它的对象的vtable选择正确的实现。
这意味着编译器不能事先知道operator++
返回的类型,但他至少需要知道它的大小,因为它是一个值(而不仅仅是一个指针)。
确实如果你有以下情况会被接受:
virtual Counter* Counter::operator++(int)
LimitedCounter* LimitedCounter::operator++(int) override
因为运行时实现在任何情况下都会返回一个指针,因此编译器能够正确处理它。
该标准规定了§10.3(C ++ 11)中允许和考虑的协变:
重写函数的返回类型应与重写函数的返回类型相同或与函数类的协变相同。如果函数D::f
覆盖函数B::f
,则函数的返回类型如果满足以下条件则是协变的:
都是指向类的指针,都是对类的左值引用,或者两者都是对类的右值引用
返回类型B::f
中的类与返回类型D::f
中的类相同,或者是类的明确且可访问的直接或间接基类在返回类型D::f
指针或引用具有相同的cv限定,并且返回类型D :: f中的类类型具有与返回类型中的类类型相同的cv-qualification或更少cv-qualification B :: F。
答案 1 :(得分:0)
这是解决这个问题的一些不同方法
将所有内容保存在一个班级中。你真的需要2个计数器类而不是可以使用计数器策略进行参数化的计数器(可以从简单的enum
到一些复杂的类)
enum class CountinngStretegy { Unlimited, Limited}
class Counter {
public:
Counter(CountinngStretegy strategy);
//...
}
让Counter
独立于LimitedCounter
。然后,如果您想在计数器类型上进行参数化,请使用以下模板:
template <typename SomeCounter> void do_smth_with_counter(SomeCounter counter);