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() const、const は UTDB_Field (基本クラス) の純粋仮想関数であり、virtual int* UTDB_intField::get_valField() constconst は派生関数 (UTDB_intField) です。

co バリアントの戻り値の型が何を意味するかについていくつかの説明を見つけましたが、私が理解したのは、戻り値の型 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;

メッセージが表示されます: type int and str are two incomparable types

比較結果 0

したがって、2 つのフィールドのタイプが同じであれば問題ありませんが、そうでない場合は、非互換性のメッセージが表示されるはずです。

どんな助けでも大歓迎です

前もって感謝します

4

1 に答える 1

2

設計上の考慮事項や意見はさておき、ここでの唯一の本当の問題は、標準から外れており、他のコンパイラではコンパイルできないことです。その理由は、標準では戻り値の型が共分散によって異なることだけが許可されているためです。つまり、オーバーロードからの戻り値の型は、基本メソッドと同じ型でなければなりません。または暗黙的にベースにキャストする派生型。これは、戻り値がポインター/参照によるものであると想定しています。

共変の戻り値の型の意図は (通常)、クラス A が何らかのルーチンから 'A *' を返すメソッドを持つことができるようにすることでした。クラス B は A から派生し、そのメソッドをオーバーロードしますが、実際には「B *」を返したいと考えています。確かに、それは 'B *' であるため、'A *' を返すと言うことができますが、追加情報が必要です。

このようにして、誰かがタイプ B のオブジェクトを使用していて、それが B であることがわかっている場合、アップキャストすることなく、メソッドが (少なくとも) B* を返すという知識を活用できます。

ここでやったことは厄介ですが、論理的には問題ありません。オブジェクトを UTDB_Field* として使用すると、メソッドは void* を提供します。これは何でもかまいません。それを UTDB_IntField* として使用する場合 (うまくいけば実際にはそうなります)、返されるものが void よりも多く、実際には int であるという追加情報がプロトタイプから得られます。

これが良いか悪いかについては触れませんが、これを他のコンパイラに移植する際の移植性の問題について知っておくことは重要かもしれません。

于 2012-04-17T16:02:31.857 に答える