生のポインターにはコンストラクターがありませんが、ほとんどの目的でコンストラクターがあるかのように使用できます。組み込み型はすべて、コピー コンストラクターを持つユーザー定義クラスと同様に、その型に変換可能な任意の型の値から初期化できます。
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);です。整数変数ではなく、関数を宣言します。