虚拟化的弃用协变返回类型

时间:2012-04-17 13:43:44

标签: c++ inheritance g++ virtual covariance

大家好我在用代码块编译我的代码时会收到一些警告,这些代码块不知道它是什么意思,应该忽略它们或者在执行期间反映在我的程序上

\src\..\inc\UTDB_Field.h|56|warning: deprecated covariant return type for 'virtual int* UTDB_intField::get_valField() const'
\src\..\inc\UTDB_Field.h|19|warning: overriding 'virtual void* UTDB_Field::get_valField() const'

实际上virtual void* UTDB_Field::get_valField() const const是UTDB_Field(基类)中的纯虚函数,virtual int* UTDB_intField::get_valField() const const是派生的(UTDB_intField)。

我找到了关于co变量返回类型意味着什么的几个解释但我理解的是返回类型void *(在我的情况下)丢失并被int *替换,对我来说这是我的目标我想要一个泛型类型的返回和每个派生类将负责自己的。

这是我的operator ==在派生类UTDB_intField:

中定义的
 virtual bool operator==(const UTDB_Field& Field) const
{
     if(this->typeF==(Field.get_typeField()))
      {
           if(this->nameF==(Field.get_nameField()))
           {
                if (this->val== Field.get_valField())
                return true;
                else
                {
                    std::cout<<" val 1: "<<*(this->get_valField())<<" and val2:  "<<*(int*)Field.get_valField() <<" are different"<<std::endl;
                    return false;
                }
            }
            else
                {
                    std::cout<<" name 1: "<<this->get_nameField()<<" and name 2: "<<Field.get_nameField() <<" are different"<<std::endl;
                    return false;
                }
      }
      else  {
                std::cout<<" type "<<this->typeF<<" and "<<Field.get_typeField() <<" are two incomparable types"<<std::endl;
                return false;
            }
};

当我用它测试时:

string  a="CurrField";
string* val=&a;
int b=5;
int* val2=&b;

std::cout<<"  *Construction*"<<endl;

UTDB_Field* UTField=new UTDB_strField("name",val);

UTDB_Field* UTField2=new UTDB_intField("Currency",val2);

std::cout<<" --------------- "<<std::endl;
std::cout<<"result of comparison "<<(*UTField2==(*UTField))<<endl;

我收到了我的消息:type int和str是两个无法比较的类型

比较结果0

因此,如果两个字段具有相同的类型,那么我知道我有什么类型,但如果它们没有,我应该有不兼容的消息。

任何帮助将不胜感激

提前致谢

1 个答案:

答案 0 :(得分:2)

撇开设计考虑因素和意见,这里唯一真正的问题是你不在标准范围内,也不会与其他编译器一起编译。原因是标准仅允许返回类型因协方差而不同。换句话说,重载的返回类型必须与基本方法的类型相同;或者隐式转换为基类的派生类型。假设返回是指针/参考。

协变返回类型(通常)的意图是,类A可以有一个从某个例程返回'A *'的方法。 B类派生自A并重载该方法,但真的想返回'B *'。当然它可以说它返回'A *',因为它是'B *',但你想要额外的信息。

这样一来,如果某人正在使用B类对象并且已知它是B,那么它可以利用该方法返回(至少)B *的知识,而不必进行上传。

你在这里做的很尴尬,但在逻辑上很好。如果您将对象用作UTDB_Field *,则该方法将为您提供可能是任何内容的void *。如果你将它用作UTDB_IntField *,它实际上是真的,那么你从原型获得的额外信息是返回的内容不仅仅是一个void ,而且确实是一个int

如果这是好事还是坏事,我不会介绍,但是了解将此问题带给其他编译器的可移植性问题可能很重要。