生のポインターにはコンストラクターがありませんが、ほとんどの目的でコンストラクターがあるかのように使用できます。組み込み型はすべて、コピー コンストラクターを持つユーザー定義クラスと同様に、その型に変換可能な任意の型の値から初期化できます。
int *i_ptr1=new int();
int *i_ptr2(new int());
同じことを意味します。
この理由は基本的にテンプレートにあると思います。つまり、型T
をユーザー定義型のように使用でき、 or と記述T t(0);
できT(0)
、T()
たまたまT
組み込み型である場合、意味はまったく同じですT t = 0;
または(T)0
または(T)0
(再び)。実際、 の意味はT(0)
定義上(T)0
、コンストラクターが何を持っていても同じT
ですが、C++ コードで C スタイルのキャストを使用しないように言う人は、その事実を無視しようとします ;-)
auto_ptr
実際にはコピー コンストラクターがありますが、ほとんどのコピー コンストラクターとは異なり、const 以外のパラメーターを取り、その引数を変更します。unique_ptr
そのため、C++11 では、コピー コンストラクターはありませんが、ムーブ コンストラクターはある が優先されて廃止されました。
Luchian が言うように、問題CarPtr au_ptr2 = new Car();
は (単なる) コピー コンストラクターではなく、 , , の型から への暗黙的な変換がないことでもnew Car();
ありCar*
ますauto_ptr<Car>
。コピーの初期化では、RHS を LHS の型に暗黙的に変換してから、それを LHS にコピーしようとします。この例では、どちらも失敗します。直接の初期化は、明示的な変換を使用することが許可されており、コピーを必要としないため、成功します。
組み込み型がコンストラクターを持っているかのように動作しない 1 つの方法は、既定の初期化です。あなたは書ける:
int i = int();
ゼロにi
初期化されることが保証されています。したがって、ゼロに設定する引数なしのコンストラクターがあると想像するかもしれません。しかし、int
本当にそのコンストラクターを持つクラス型である場合は、次のように記述します。
int i;
また、ゼロであることを保証i
しますが、そうではありません(少なくとも、関数スコープではありません)。
ところで、これらすべてに興奮しすぎて、いわゆる「最も厄介な解析」を誤って呼び出してはいけません。
int i();
int i(void);
ではなくと同等int i(0);
です。整数変数ではなく、関数を宣言します。