better-C

というわけで強制労働させられているわけだが、
先に似た作業をしていた、もう一人のプログラマことnetcrawlerから
ターゲット環境用だと何故かC++の仮想関数が正しく動かないという情報を
かなり前の時点で得ていた。
恐らくグローバルコンストラクタが動いていないのではないかと思うのだが、
コンパイラ/リンカは別環境で使ったものと同じなはずだし、
実験して、リンカの機能調べて、それでも解決しなかったら困るのと、
脅迫された後の強制労働なんで、
ソースがどうなろうが知ったこっちゃないので、
C++なのにコンストラクタ/デストラクタに頼らず、virtualも使わないという
これなんていうCFront0.0.1?みたいなコードに書き直している--;
本当は完全なCのコードにしようかと思ったのだけど、
HOGE_GetName(pHoge);みたいな名前にいちいち全部変えるの面倒だし、
ということで、virtualだった関数を全て非virtualにし、
インスタンスに個別に関数ポインタを持たせるという荒業で書き換えてる--;
もともと


class Base
{
 public: virtual void Process(int arg);
};
だったのを

class Base
{
 protected: typedef void(*ProcessFunc)(Base*, int);
 
 protected: ProcessFunc m_pProcess;
 
 public: void Process(int arg) { m_pProcess(this, arg); }
};
こんな感じに書き直してる--;
サブクラスでは

class Derived : public Base
{
 private: static void STATICHOOK_Process(Derived* pThis, int arg) { pThis->IMPL_Process(arg); }

 public: void InitializeFuncPtr() { m_pProcess = (ProcessFunc)&STATICHOOK_Process; }
 
 private: void IMPL_Process(int arg) { /* ここにやっと実装ができる */ }
};

こんなことしてる。
もともとVTableに一個しかない関数ポインタ分を全インスタンスが持つことになるので
使用メモリが多少増えるが、今回は許容範囲だろう。
ベースクラスの関数ポインタのアクセス制限もprotected:なメンバ変数という最悪の選択肢を選んでいるが、先ほども書いたように究極的やっつけ仕事なのでもう知らない。

とりあえず今日作業した分まではこれで上手く行っているが、
この選択が吉と出るか凶と出るか、正直ちょっと不安である。