bcc32.exeの拡張構文"__property"と仮想関数
アクセスメソッドは多用しても、プロパティは標準C++に無いからあまり使っていなかったけど、「シンタックスシュガー」としては激しく便利。 ただ、仮想関数との兼ね合いがちょっと気になったので試してみた。
//--------------------------------------------------------------------------- #include <iostream> #pragma hdrstop #include <tchar.h> //--------------------------------------------------------------------------- class CBase { public: CBase() : m_Attribute(0) { } virtual ~CBase() { } protected: int m_Attribute; public: // アクセスメソッド(ゲッター) virtual int GetAttribute() const { return m_Attribute; } // アクセスメソッド(セッター) virtual void SetAttribute(int Value) { m_Attribute = Value; } // bcc32の拡張構文を使用した「プロパティ」の定義 __property int Attribute = {read = GetAttribute, write = SetAttribute}; }; class CFoo : public CBase { void SetAttribute(int Value) { // 継承クラスのセッターでは負数を受け付けない if (Value < 0) Value = 0; m_Attribute = Value; } }; #pragma argsused int _tmain(int argc, _TCHAR* argv[]) { // 基底クラスのプロパティ CBase Base; Base.Attribute = 100; std::cout << "Base.Attribute = " << Base.Attribute << std::endl; // 派生クラスのプロパティ CFoo Foo; Foo.Attribute = 200; std::cout << "Foo.Attribute = " << Foo.Attribute << std::endl; Foo.Attribute = -1; std::cout << "Foo.Attribute = " << Foo.Attribute << std::endl; // 多態でプロパティ CBase* pBase = new CFoo(); pBase->Attribute = 300; std::cout << "pBase->Attribute = " << pBase->Attribute << std::endl; pBase->Attribute = -400; std::cout << "pBase->Attribute = " << pBase->Attribute << std::endl; delete pBase; return 0; } //---------------------------------------------------------------------------
出力結果
Base.Attribute = 100 Foo.Attribute = 200 Foo.Attribute = 0 pBase->Attribute = 300 pBase->Attribute = 0
C++Builder(bcc32.exe)の拡張構文"__property"はDelphiやC#、Rubyのプロパティ(属性)をC++でサポートする拡張構文。C++Builderにおける__propertyの具体的な使い方と概要はここで。
基底クラスでアクセスメソッドを仮想関数にしておけば、派生クラスのプロパティもオーバーライドした関数を呼び出してくれる。