「コンストラクタ」の版間の差分

削除された内容 追加された内容
導入部wikify
タグ: 差し戻し済み
1行目:
'''コンストラクタ'''{{sfn|JISX3014|2003}}{{lang-ja-short|構築子}}{{efn|JIS X 3015「プログラム言語C#」{{sfn|JISX3015|2008}}では、instance constructorをインスタンス構築子、static constructorを静的構築子、default constructorを省略時構築子と訳している。JIS X 3060「ECMAScript言語」{{sfn|JISX3060|2000}}では構築子という訳語が使われている。}},{{lang-en-short|constructor}})は、[[オブジェクト指向]]の[[プログラミング言語]]で新たな[[オブジェクト (プログラミング)|オブジェクト]]を生成する際に呼び出されて内容の初期化などを行なう[[サブルーチン|関数]]あるいは[[メソッド (計算機科学)|メソッド]]のことである。対義語は[[デストラクタ]]。
 
オブジェクトの生成は、
# メモリ割当({{lang-en-short|allocation}})
# 初期化({{lang-en-short|initialization}})
の二段階を経て行なわれるが、コンストラクタ構築子を持つプログラミング言語ではメモリ割り当ては言語機能に組み込まれ、初期化用のコードのみを記述するのが普通である。
 
[[日本産業規格|JIS]]では、「構築子」という直訳が割り当てられている規格もあるが{{efn|JIS X 3015「プログラム言語C#」{{sfn|JISX3015|2008}}では、instance constructorをインスタンス構築子、static constructorを静的構築子、default constructorを省略時構築子と訳している。JIS X 3060「ECMAScript言語」{{sfn|JISX3060|2000}}では構築子という訳語が使われている。}}、「コンストラクタ」という用語が使われている規格もある{{efn|JIS X 3014「プログラム言語C++」{{sfn|JISX3014|2003}}を参照。}}。
 
== クラスベース言語でのコンストラクタ 構築子==
[[C++]]、[[Java]]、[[C Sharp|C#]]、[[PHP (プログラミング言語)|PHP]]など、[[クラスベース]]のオブジェクト指向言語では、コンストラクタ構築子は[[クラス (コンピュータ)|クラス]]のメンバとして定義される。
 
C++、Java、C#のコンストラクタ構築子は、「クラス名と同一の名前を持ち、戻り値指定のない関数(メソッド)」であるかのような記法となっている。以下にJavaの例を示す。
 
<syntaxhighlight lang="java">
23 ⟶ 22行目:
</syntaxhighlight>
 
なお、{{要出典範囲|date=2020-08|コンストラクタ構築子について「クラス名と同一の名前を持つ関数(メソッド)」と説明している場合がある}}が、C++やJavaでは厳密にいえばこれは誤りであり、コンストラクタ構築子には名前はない。C++では「クラス名と同一の名前を持つメンバー関数」を定義することはできない。一方、Javaでは「クラス名と同一の名前を持つメソッド」を、コンストラクタ構築子とは別に定義可能であるが、これは混乱を招くだけでなく、「クラス名を大文字で始め、メソッド名を小文字で始める」というJava公式の慣習に反することにもなるため、通例コーディング規約で禁止または非推奨とされている<ref>[https://future-architect.github.io/coding-standards/documents/forJava/Java%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E8%A6%8F%E7%B4%84.html#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89 Javaコーディング規約 | Future Enterprise Coding Standards]</ref><ref>[https://rules.sonarsource.com/java/RSPEC-1223 Java: Non-constructor methods should not have the same name as the enclosing class]</ref>。
 
また、PHPでは<code>__construct</code>、[[Ruby]]では<code>initialize</code>というように、特定の名前を持つメソッドを作ればそれがコンストラクタ構築子になる、というプログラミング言語も存在する。
 
コンストラクタ構築子に渡す[[引数]]により初期化のバリエーション変種が定義される。特にパターンと頻出名前をもつコンストラクタは持っている構築子を以下であるに示す
; 既定構築子
; デフォルトコンストラクタ
: 引数なしで呼び出すことができるコンストラクタ構築子のことである。通常は引数のないコンストラクタ構築子であるが、C++ では全ての引数にデフォルト既定引数が指定されているコンストラクタ構築子も引数なしで呼び出すことが可能なためデフォルトコンストラクタ既定構築子と呼ばれる。
; 複製構築子
; コピーコンストラクタ
: 同一クラスのオブジェクトを基に、同一内容のオブジェクトを作成するコンストラクタ構築子。複製を作る。ムーブコンストラクタ移動構築子と異なり、コピー複製元のオブジェクトが書き換えられることはない。
; 移動構築子
; ムーブコンストラクタ
: 同一クラスのオブジェクトを基に、同一内容のオブジェクトを作成するコンストラクタ構築子コンストラクタ構築子内では、内部状態をムーブ元のオブジェクトから自身のオブジェクトに移動する。すなわち、ムーブ元のオブジェクトの内容は破壊される(ムーブコンストラクタ移動構築子実行前と異なる状態となる)。[[C++11]]で正式に導入された<ref>{{Cite book |和書 |last=Mayers |first=Scott |authorlink=:en:Scott Meyers |coauthors= |others=千住治郎 |date=2015-09-16 |title=Effective Modern C++ |publisher=オーム社 |page=107 |id= |isbn=978-4-87311-736-2 |chapter=3章 現代のC++への移行 項目17:自動的に生成される特殊メンバ関数を理解する |quote=C++11から、ムーブコンストラクタとムーブ代入演算子の2つが追加されました。}}</ref>。
; 構築子鎖
; コンストラクタチェーン
: 引数の異なる複数のコンストラクタ構築子チェーンのように一つのコンストラクタ構築子へ結び付けること。単純なものから複雑なものへ流すことで初期化コードの重複を防ぐ。[[C++11]]では委譲コンストラクタ構築子が言語機能として実装された。
 
== JavaScriptのコンストラクタ構築子 ==
[[JavaScript]]は[[プロトタイプベース]]のオブジェクト指向言語であるため、クラスは存在せず、[[new演算子]]付きで通常の関数を呼び出すことで、コンストラクタ構築子として動作させることができる<ref name="atit_4_1">{{cite web | url=http://www.atmarkit.co.jp/fdotnet/ajaxjs/ajaxjs04/ajaxjs04_01.html | title=連載:Ajax時代のJavaScriptプログラミング再入門 第4回 JavaScriptでオブジェクト指向プログラミング Page1 | publisher=[[@IT]] | date=2007年9月25日 | accessdate=December 13, 2011 | author=山田祥寛}}</ref>。関数をコンストラクタ構築子として呼び出すと、[[this (プログラミング)|<code>this</code>]]は新しく生成されるオブジェクトを指すようになり<ref name="atit_4_1" />、また[[プロトタイプ]]も設定される<ref name="atit_4_2">{{cite web | url=http://www.atmarkit.co.jp/fdotnet/ajaxjs/ajaxjs04/ajaxjs04_02.html | title=連載:Ajax時代のJavaScriptプログラミング再入門 第4回 JavaScriptでオブジェクト指向プログラミング Page2 | publisher=[[@IT]] | date=2007年9月25日 | accessdate=December 13, 2011 | author=山田祥寛}}</ref>。
 
なお、[[ECMAScript]] 2015 (ES6) 以降は[[糖衣構文]]としてクラスもサポートする。