0

ほとんどの OOP の本や記事では、コンストラクターについて次のように説明しています。

コンストラクターはクラスの特殊なメソッドであり、その名前はクラス名と同じであり、戻り値の型はありません。

したがって、コンストラクターは次の形式になります。

class MyClass {
    public: /* no return type */ MyClass();
}

さて、この定義は OOP の原則と矛盾しています: メソッドは (たとえ であってもvoid) 戻り値の型を持つ必要があり、オブジェクトでは同じ名前の 2 つのメンバーを持つことはできないため、メソッドはクラスの名前と同じ名前を持つことはできません。

定義を次のように変更できると思います。

コンストラクターはクラスの特殊なメソッドであり、名前がなく、匿名または名前のないメソッドであり、その戻り値の型はクラス (の型) です。

したがって、次のようになります。

class MyClass {
    public: MyClass /* no method name */ ();
}

2 番目の定義では、ほとんどの OOP 言語で匿名メソッドを使用することが許可されており、メソッドには実際の戻り値の型があります。

var obj = new MyClass(); 

コンストラクターが呼び出され、objのインスタンスでMyClassあるため、コンストラクターには戻り値があります。一方、new MyClass()は、 という名前のオブジェクトのブループリントでアクセス可能な匿名メソッドを呼び出すためのコントラクトですMyClass

どう思いますか?私は間違っていますか、それともこの定義を使用できますか、またはこの観点からコンストラクターを見ることができますか?

更新: 投票を取り下げてクローズするのはなぜですか? 説明してください。

4

2 に答える 2

4

オペレーターnewは次の 2 つのことを行います。

  1. 新しいオブジェクトにメモリを割り当てます (例では、そのメモリ部分へのポインタが obj に割り当てられます)。
  2. オブジェクトをデフォルト値で初期化するコンストラクターを呼び出します。

その意味で、コンストラクターは何も返しません。newオブジェクトを返すのは演算子です。コンストラクタはデコレータとして機能します。メモリの一部を受け取り、そのメモリ内のさまざまなバイトをデフォルト値で初期化します。

また、コンストラクターには戻り値の型が必要であるという最初のポイントにも答えます。コンストラクターは、オペレーターによって割り当てられた一部のデータのみを初期化するnewため、何かを返すことはできませんnew MyClass()。実際、何かを返したい場合、式は同時に 2 つの型を返す必要があるためです!! 1 つの型はオペレーターによって割り当てられたオブジェクトnewであり、2 番目の型はコンストラクターによって装飾された同じオブジェクトです。

定義にこだわりたい場合methodは、説明の名前を別のものに変更することをお勧めします (デザイン パターンのように、デコレータなど)。

そして、メソッドが型を返さなければならないと誰が言いましたか? 抽象メソッドはどうですか? それらは何かを返しますか?

編集していくつかの質問に答えます:

ええ、抽象メソッドには戻り値の型がありますが、実際には何も返さず、定義したインターフェイスを実装するメソッドのみを返します。私の要点は、メソッドとして定義されているものすべてが型を返さなければならないわけではないことを示すことでした。メソッド (または言語構成体) の中には、呼び出し方に関係なく、何かを返すものと返さないものがあります。

コンストラクターの場合、実際には何も返さないという事実を除けば、他の通常のメソッドと非常に似ているため、何も返さないメソッドの観点からそれらを定義する方が簡単だったと思います。何も返さないメソッドのような構造の別の定義を作成しようとしています。

オペレーターはcreate an objectnewとは言いません。それは単なる演算子、言語構造です。コードがコンパイルされて実際に存在しなくなると、オブジェクトを表すメモリの一部を割り当てて初期化するためのアセンブラー コードに置き換えられます。new

new MyClass()実行時に実行する手順を 1 つずつ分解してみましょう。

  1. Operatorは、クラスのすべての変数とメタデータをそのすべての親クラスと子クラスと共にnew格納するために必要なサイズのメモリを割り当てます。MyClass
  2. オペレーターは、class のすべての親クラスMyClass(存在する場合) のコンストラクターを実行するようになりました。
  3. この演算子は、 class のすべての子クラスのコンストラクターを実行します (組み込みクラス自体ではないMyClass、格納されているメンバー変数)。MyClass
  4. オペレーターは、最終的にクラスのコンストラクターを実行しMyClassます。
  5. オペレーターnewは、作成されたオブジェクト (または割り当てられたメモリーへのポインター) を返します。

実行するコンストラクターが 1 つしかないことはほとんどありません。クラスに親クラスがあり、内部にカスタム クラスを保持しているnew場合、オブジェクトを返す前に、オペレーターは数十回とは言わないまでも、数回のコンストラクターを実行する必要があります。各コンストラクターが何かを返さなければならない場合、すべての戻り値の型はどこに行くのでしょうか? また、コンストラクターが返すもので何もできない場合、それを行うポイントは何でしょうか?

オペレーターはどんな動物?

ここで紛らわしいのは、演算子の定義だと思います。Operator は呼び出すメソッドではありません。オブジェクトを作成すると言う思考は、2 つのオブジェクトを追加すると言う、またはオブジェクトを比較するとnew言うのと同じくらい間違っています。演算子はオーバーロードできますが、原則として、演算子は、言語 (コンパイルされたアセンブル コード) が実行する操作を定義する言語構成要素です。たとえば、変数に 2 つのオブジェクトの合計を割り当てる、オブジェクトを作成するなどです。ウィキペディアの演算子を参照してください。+=

于 2013-05-14T22:32:07.667 に答える
0

本でコンストラクターのどのような記述が使用されているかは誰が気にしますか? なぜセマンティクスを気にするのですか?

コンストラクターの唯一の目的は、オブジェクトを構築してインスタンス化することであり、オブジェクトがなければ OOP はありません。コンストラクターは何かを行い、値を再実行しないため、多くの本で「特殊なメソッド」とラベル付けされています。特殊化されたという言葉は、署名に void キーワードを必要としないため正確に使用されます。

コンストラクターが何をどのように行うかは非常に明確なので、質問は、コンストラクターが文献で適切に説明されているかどうかに帰着します。たまたまそうだと思いますが、「専門化された」という言葉が使用されているという理由だけで、ポイントは何ですかそのレベルの解剖で時間を無駄にするのですか?

ソース (MSDN) に直接アクセスすると、C# プログラミング ガイドのコンストラクターでこれを見つけることができます。

クラスまたは構造体が作成されるたびに、そのコンストラクターが呼び出されます。クラスまたは構造体には、異なる引数を取る複数のコンストラクターが含まれる場合があります。コンストラクターを使用すると、プログラマーはデフォルト値を設定したり、インスタンス化を制限したり、柔軟で読みやすいコードを記述したりできます。

おわかりのように、MSDN はコンストラクターを "特殊なメソッド" (またはその他のもの) としてラベル付けしていません。コンストラクターとは何か、その目的は何かを明確かつ簡潔に説明しているだけです。それは彼らがフレームワークを設計した方法のほんの一部であるため、一部の作成者がコンストラクターを説明するためにどのような比喩を使用しているかはまったく関係ありません...

最後に、「フレームワーク設計ガイドライン」を引用します。

完璧なデザインなどというものはありません。設計とはトレードオフを行うことであり、正しい決定を下すには、オプション、その利点、および欠点を理解する必要があります。トレードオフのない設計だと思っている場合は、特効薬を見つけるのではなく、何か大きなものを見逃している可能性があります。

コンストラクターをそのままにすることは、その引用で説明されているようなトレードオフと簡単に見なすことができます。

于 2013-05-14T23:11:42.803 に答える