『class』の初期化をインストラクタコンストラクタに記述するけど…
普通は、こう書く…多分…。
class A{
int element;
...
A():element(0),...{}
...
};
でも個人的には、こちらが好き♪
A(){
element=0;
...
}
は、置いといて。
クラスの要素を一元的にかつ確実に初期化する方法を考えていた。
で、本を読んでいたらC++では、『class≒struct』だと読んだので
構造体をクリアする方法を試してみた。
そしたら使えちゃった…。
正直「え!?」って感じ。
で直すとこうなる。
class A{
int element;
//... 要素が多種多数、開発途中で後々増えることも…
A(){memset(this,0,sizeof(*this))};
//... 関数、開発途中で増減当たり前!
};
こうすれば、インストラクタコントラクタを書き換えず
変数領域の0クリアーが保証される。
開発途中の変数増減で未初期化バグなど喰らいたくないです。
あとクリアするのなら個別にやるより、「memset」の方が早いし…。
勿論、0クリアーしたらまずい所は、個別に対応する必要がある。
実際に問題ないか調べてみる。
インターネットとか本で調べてたけど…
あまりにマイナーな内容なのでちょっと見付からない…。
困っていると…
そうか!目の前にデバッガがあるじゃないか!
実際にクラスを作って参照アドレス確認すればいいじゃん♪
で、やってみた。
#include<stdio.h>
#include<memory.h>
typedef class S{
public:
int element;
//... 変数郡
S(){memset(this,0,sizeof(*this));}
void f(char*s){printf(s);}
// virtual void g(char*s){printf(s);}
// virtual void h(char*s){printf(s);}
//... 関数郡
}S, *LPS;
void main( void ){
S s;
printf( "%8X, %8X, %8X, %8X, \n", s.element, &s.element, s.f, sizeof(s) );
}
上記の結果
0, 12FF7C, 40104B, 4,
その他も調べてみると…
「virtual」を使用すると、先頭に「vftable」ポインタの
4バイトが確保され上記のままでは、ここを書き潰すので
「virtual」禁止の縛りが付く。
「sizeof」でのサイズが4バイト増えるの確認できる。
ちなみに、『struct』で「virtual」を使用すると<しないと思うけど…。
やっぱり4バイト増えます。
まあ、使ったら初期化を「memset((char*)this+4,0,sizeof(*this)-4);」に
すれば良い訳だ。
4バイとは、「virtual」の数に関係しないからこれでOK♪
で、詳しい人に聞いてみたらこうしたら良いんじゃないと
教えてもらったのがこれ。
typedef class S{
public:
char start;
int element;
//... 要素が一杯、開発途中で後々増えることも…
char end;
S(){memset(&start,0,&end-&start);}
//... 関数郡
}S, *LPS;
なんて魅力的なんだ!
これから使ってみよう♪
2007年12月28日追記--------------
STSKさんから
>な、なんだ?インストラクタって…。
>コンストラクタなら解るケド。
との書き込みがりましたので修正しました。(汗)
インスタンスとコンストラクタを変に混ぜこぜにして
覚えてしまったみたいです…。
その後、間違いに気が付いて修正したのですが…
ブログまで気が回りませんでした…。(^_^;)
まあ、如何にボケか分かる事例として
末永く残す所存でございます…。
すみません…。
最近のコメント