Java互換ライブラリ(3)
Imageクラスをvirtualに出来ないと言うことは、インターフェースクラスを作るのは無理なのでしょうか?
あれですね。Imageクラスは、あくまで実体へのポインタを持ったダミーのクラスです。
そいつを直接呼び出して派生元を呼び出そうとしたのがそもそもの間違いのような気がします。
つまり、Data系のクラスをvirtualにすればいいのです。
class Image : public Object{ private: class ImageData : public Object::ObjectData{ virtual Graphics getGraphics() = 0; friend class Image; }; private: // _pDataはObjectDataへのポインタを持ったスマートポインタ ImageData* getData(){ return (ImageData*)(_pData.get()); } public: Image(){} Image( const Object& s ) : Object( s ){} Image( Object* p ) : Object( p ){} Graphics getGraphics(){ return getData()->getGraphics(); } friend class ImageData; }; class ImageEx : public Object{ private: class ImageExData : public Image::ImageData{ virtual Graphics getGraphics(); friend class ImageEx; }; private: ImageExData* getData(){ return (ImageExData*)(_pData.get()); } public: ImageEx(){} ImageEx( const Object& s ) : Image( s ){} ImageEx( Object* p ) : Image( p ){} Graphics getGraphics(){ return getData()->getGraphics(); } friend class ImageExData; };
Data系のクラスへのポインタを取得し、ポインタを介してメソッドにアクセスします。
そうすれば仮想テーブルアクセスになるので、ImageExで作られたクラスをImageクラスにキャストしても、無事ImageExクラスのgetGraphics()が呼ばれることになります。
これでvirtual呼び出しの問題は解決ヽ(´ー`)ノ
ただ、メソッドがたくさんある場合は、その委譲メソッドを書くのが非常に面倒なんですよね(;´Д`)
まあ、実データへのポインタを内部に隠蔽しているんだから当たり前といっちゃ当たり前なんですが……。