コンポーネント作成における属性継承の注意事項


C++では、関数のオーバーライド(override,注:多くの文章や本でoverrideをリロードとも呼ぶのは妥当ではないと思いますが、ここでDelphi用語「オーバーライド」(overload)と「リロード(overload)」で区別)を借りて、ベースクラスでvirtualキーワードで修飾され、虚関数数と呼ばれ、派生クラスでベースクラスの虚関数をオーバーライドすると、派生クラスを指す親ポインタを使用してこの関数を呼び出すと、派生クラスのバージョンが実行されます.
例:
#include <iostream>
using namespace std;

class a {
public:
   virtual void Hello() {cout<<"Class a"<<endl;}
};
class b : public a {
public:
   void Hello() {cout<<"Class b"<<endl;}
};

int main(int argc, char* argv[])
{
   a *ia = new a;
   ia->Hello(); //  "Class a"
   a *ib = new b;
   ib->Hello(); //  "Class b"
   delete ia;
   delete ib;
   return 0;
}

CBuilderとDelphiでは__が追加されましたプロパティと呼ばれるpropertyキーワードです.読み取り方法と書き込み方法を指定したり、変数アクセスを直接行うことができます.たとえば、次のようにします.
__property AnsiString Name = {read=FName, write=SetName}; //TComponent  Name    。

(CBuilder/delphi約定によると、直接アクセスする変数名はアルファベットFで始まり、読み方はGet+属性名、書き方はSet+属性名)
TComponentから新しいクラスTMyCompを派生し、Nameプロパティを再定義すると、次のような状況に遭遇する可能性があります.1.Nameの設定時の動作を処理するために、書き込み方法SetNameを再定義し、内部にFNameという変数も定義しました.
__property AnsiString Name = {read=GetName, write=SetName}

このようにすると、最初の場合、ベースクラスTComponentのFNameではなく、TMyComp内部のFNameに対するNameの付与であるため、上書きの効果は得られません.救済策は、TMyCompのFName変数を除去し、ベースクラスのFNameをprotectedセグメントに配置して派生クラスに直接アクセスできるようにすることです(派生クラスがFNameに値を付与しているのにFNameの定義が見つからないため、派生クラスがFNameの定義を発見しないことがよくあります).
2.プロパティを再宣言し、読み取り方法を変更
2つ目のケースではGetNameの読み取り方法が宣言されていますが、基本クラスTComponentでは虚関数GetNameが宣言されていないため、この2つのケースでは次のように書きます.
TComponent *MyComp = new TMyComp(NULL);
MyComp->Name = "Hello";
ShowMessage(MyComp->Name);

最後に表示されるのは、あなたが望んでいる「Hello」ではなく空の文字です.したがって、ベースクラス属性の宣言に読み書きメソッドの1つが直接変数付与または非虚関数メソッドである場合.上書きの効果を達成するには、派生クラスでこのプロパティを上書き定義することはできません(ただし、関数上書きという重要なパフォーマンスを失うことを気にしない限り、制限レベルを下げたり、デフォルト値を変更したり、読み取り専用に設定したりすることができます).
(ちょっとした経験ですが、間違ったところがあればご意見をどうぞ)