【C++】ユーザー定義コンストラクタを作ると、コンパイラはデフォルトコンストラクタを自動生成しない
本記事では、「プログラマ自身がコンストラクタを定義した場合でも、C++コンパイラはデフォルトコンストラクタを自動的に生成するのか?」というよくある疑問について、サンプルコードとともに分かりやすく解説します。
C++の基本的なルールとして、クラスにコンストラクタがひとつも定義されていない場合に限り、コンパイラは引数なしで呼び出せる「デフォルトコンストラクタ」を暗黙的に生成します。一方、ユーザーが何らかのコンストラクタ(例:引数付きのコンストラクタ)を定義した瞬間、コンパイラによるデフォルトコンストラクタの自動生成は行われなくなります。
例1:コンストラクタを一切定義しない場合
#include<iostream>
using namespace std;
class myInteger{
private:
int value;
// クラス内のその他の関数
};
int main(){
myInteger I1; // デフォルトコンストラクタが自動生成されるためOK
getchar();
return 0;
}このコードは正常にコンパイルできます。myIntegerクラスにはコンストラクタが定義されていないため、コンパイラが暗黙のうちにデフォルトコンストラクタを用意してくれるからです。
例2:引数付きのコンストラクタを定義した場合
#include<iostream>
using namespace std;
class myInteger{
private:
int value;
public:
// ユーザー定義コンストラクタ(引数付き)
myInteger(int v){ value = v; }
// クラス内のその他の関数
};
int main(){
myInteger I1; // エラー:引数なしのコンストラクタは存在しない
getchar();
return 0;
}このコードはコンパイルエラーになります。ユーザー定義コンストラクタが存在するため、コンパイラはデフォルトコンストラクタを生成せず、「引数なしのコンストラクタが未定義」という旨のエラーが出ます。
ポイントまとめ
- コンストラクタが1つも定義されていない場合のみ、コンパイラはデフォルトコンストラクタを自動生成する。
- ユーザーが任意のコンストラクタを定義した時点で、デフォルトコンストラクタの自動生成は行われない。
- 引数付きコンストラクタだけを定義しつつ、引数なしでのインスタンス化も許可したい場合は、デフォルト引数を持たせるか、C++11以降では
= defaultを使って明示的にデフォルトコンストラクタを要求できます。
例:myInteger() = default;
この挙動を理解しておくと、「なぜ引数なしでオブジェクトを生成できないのか」というコンパイルエラーの原因を素早く特定できるようになります。
-
C++のローカル変数とグローバル変数はデフォルトでどのように初期化されるのか?
C++における変数の初期化には、ローカル変数とグローバル変数のどちらにも共通する重要なルールがあります。基本的に、変数を宣言すると、明示的に指定しない限り、コンパイラがそのデフォルトコンストラクタを呼び出します。言語レベルの型(組み込み型)の場合ポインタ、int、float、bool などの言語レベルの型(プリミティブ型)の場合、その「デフォルトコンストラクタ」は実質何もしません。宣言された時点でメモリの内容はそのまま放置されます。つまり、これらの変数にはほぼ何でも入り得ます。なぜなら、そのメモリ領域に以前何が格納されていたのか、あるいはそのメモリ自体がどこから確保されたものなのか、通常は保証
-
Javaでデフォルトコンストラクタを作成する方法をわかりやすく解説
デフォルトコンストラクタ(引数なしコンストラクタ)とは引数なしのコンストラクタ(No-arg constructor)は、パラメータを一切受け取らず、クラスのフィールドをそれぞれのデフォルト値で初期化します。具体的には、オブジェクト型には null、float 型と double 型には 0.0、boolean 型には false、byte・short・int・long 型には 0 が設定されます。なお、コンストラクタを明示的に呼び出す必要はありません。オブジェクトが生成される(インスタンス化される)タイミングで自動的に呼び出されます。コンストラクタを定義する際のルールコンストラクタを定義する