昨日の実習の copy constructor と operator=、くどいけど、もっかいおさらい。
明示的に実装されていない場合、
は、親クラスのものが継承されず、自動生成される。
これらの member function が継承されないのは子クラスに新たな data member が加えられた場合、そのメモリー領域の確保あるいは解放、複製のため、親クラスのものを継承することができない(無理にするとまともに動かないことは容易に想像できるであろう)ためである。ただし、継承されないと言うことは、必ずしも親クラスのものが使われないと言うことを意味しない。実際、これらの
member function が自動生成された場合には、以下に述べるように、親クラスへと連鎖する。
constructor の作業は
の順で行われる。
注意すべきなのは、1〜2にあるように自分で constructor を実装した場合、仮に親クラスやいくつかの data member の constructor を明示的に呼んでいなくても、それらの default constructor を呼ぶように initializer が補完されるということである。つまり、こうすることにより、先祖代々にわたって全ての data member のメモリー領域の確保が、少なくとも default constructor が呼ばれることによって保証される。
これは copy constructor でも同様である。copy constructor を明示的に実装した場合、親クラスの copy constructor への連鎖を initializer や constructor 本体で明示的にしない場合でも、default constructor は連鎖していく。ただし、この場合、親クラスの data member のコピーが行われないことは言うまでもない。また、initializer ではなくて copy constructor の本体で単純代入により data member のコピーを行う場合があるが、これは、initalizer にその data member の default constructor が補完されることでにょろ括弧に入る前に作られた data member の instance に対する代入演算を行っていることになる。単純代入で良いのならば intializer で copy constructor を使うべきである。
int、float、double などの単純型の initializer も copy constructor と見なせることに注意する。この場合も、にょろ括弧の中で代入する場合には、initializer にこれらの単純型の data member の default constructor が補完され、そこで単純型オブジェクトが default construct されてから、本体で代入が起こると考えられる。
自動生成の default constructor の場合、上の1〜3に対応させると、
となる。1〜2は自動生成で initializer が生成されたと解釈できる。
自動生成の copy constructor の場合は、
となる。この場合も1〜2は自動生成で initializer が生成されたと解釈できる。
● 注意
destructor の作業は、constructor の場合を正確に逆にたどることになる。
つまり、
の順で行われる。2〜3は暗黙であり、自動生成の destructor の場合は1がないのでこの部分だけとなる。2〜3により、destructor は常に連鎖する。
constructor は多重的議できるが、destructor は各クラスに1つしかないので、constructor の場合のように連鎖が途切れることはない。