Humanity

Edit the world by your favorite way

コピーコンストラクタについて

pimplイディオムというのがEffective C++で紹介されてたのでふとググってみた。
そんで検索結果の一番最初のサイトが検索結果の一番最初に出たので見てみたら、pimplイディオムとは違う所でいかに自分がC++の基本を理解していないか思い知らされた。


以下説明に必要な所だけ転載。

hoge.h

#include "foo.h"
#include "bar.h"

class hoge {
private:
    foo f;
    bar b;
public:
    hoge();
    foo& get_foo();
    bar& get_bar();
};


hoge.cpp

#include "hoge.h"

hoge::hoge() {}
foo& hoge::get_foo() { return f; }
bar& hoge::get_bar() { return b; }


foo.h

class foo {
public:
...
foo& operator =(const foo& rhs) {
    throw not_implemented_error(); // how stupid I am!
}
... 
};
hoge a;
hoge b;
a = b;


で、

a = b;

の時点で例外が投げられると書いてあるんだけど、
自分は

  1. hogeのコピーコンストラクタは定義されてないので、コンパイラにより自動生成される
  2. そのコピーコンストラクタメンバ関数と変数をビットレベルでコピーする
  3. なのでメンバ変数fのoperator=(const foo& rhs)は実行されない
  4. なので例外も発生しない

と思ってたんだけどどうやら違うらしい。

検索すると同じようなことを言ってる人がいた。(なんかサイトに繋がらなかったのでキャッシュで見た)

元記事
キャッシュ

この場合、クラスの(自動生成される)代入演算子、コピーコンストラクタ内では、vectorのポインタではなく中身(実体)をコピーしてくれるのね。
自動生成されるコードは、単純にビットコピーではなく、順々メンバのコピーコンストラクタが呼び出されるような気配。

初めて知った。(単純なビットコピーと信じていたので、自動生成で十分なコピーコンストラクタを一所懸命書いてしもうた)

初めて知った。
よくビットレベルでコピーされるとか聞くんだけど違うのか。
なんかポインタの解説とごっちゃにしてたような気がする。


正しくは

  1. 自動生成されるコピーコンストラクタは単純にビットコピーではなく、順々にメンバのコピーコンストラクタが呼ばれる
  2. ただしメンバがポインタであった場合はそのアドレスがコピーされる

ってこと?うーんよくわからない


たしかにintのコピーコンストラクタはあってもポインタ型にはないもんなぁ。
(あったとして初期化はどうなるんだろう。
int*(0)とかint*(0xFFFF)とか。。。)