1

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

\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() constconst 是 UTDB_Field(基类)中的纯虚函数,而virtual int* UTDB_intField::get_valField() constconst 是派生的(UTDB_intField)。

我发现了一些关于 co variant 返回类型的含义的解释,但我的理解是返回类型 void*(在我的情况下)丢失并被 int* 取代,对我来说,这是我的目标,我想要一个通用类型return 并且每个派生类将负责自己的。

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

 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;

我得到我的信息:类型 int 和 str 是两种无与伦比的类型

比较结果 0

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

任何帮助将不胜感激

提前致谢

4

1 回答 1

2

撇开设计考虑和意见不谈,这里唯一真正的问题是您超出了标准,并且无法与其他编译器一起编译。原因是标准只允许返回类型因协方差而不同。换句话说,重载的返回类型必须与基方法的类型相同;或隐式转换为基类的派生类型。这假设返回是通过指针/引用。

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

这样,如果有人使用 B 类型的对象并且已知它是 B,它可以利用该方法返回(至少)B* 的知识,而无需向上转换。

你在这里所做的很尴尬,但逻辑上很好。如果您将该对象用作 UTDB_Field*,则该方法会为您提供一个 void* ,它可以是任何东西。如果您将它用作 UTDB_IntField*(希望它确实如此),那么您会从原型中获得额外信息,即返回的不仅仅是一个 void ,而且确实是一个 int

我不会讨论这是好是坏,但了解将其带到其他编译器的可移植性问题可能对您很重要。

于 2012-04-17T16:02:31.857 回答