struct A { A(A* = 0) {} void foo() {} }; int main() { A obj = new A(); obj.foo(); return 0; }
上記のコードはコンパイルも実行も普通にできます。最初見たときはちょっとびっくりしましたが、普通にコンストラクタが呼ばれるんですね。当然、 new で確保した領域を解放していないので、このプログラムはメモリリークを起こします。
実際の例は CDialog クラスから派生したクラスでしたが、 VC のクラスウィザードで生成するダイアログクラスはコンストラクタの引数に CWnd* を取るので動いてしまったのでしょう。
こういった現象を起こさないようにするには、コンストラクタに explicit 指定子をつけます。
struct A { explicit A(A* = 0) {} void foo() {} }; int main() { A obj = new A(); // error! obj.foo(); return 0; }
クラスウィザードで生成されるクラスのコンストラクタも自動的に explciit にしてくれてもいい気がしますね。