問題タブ [constructor-chaining]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
398 参照

syntax - Boo コンストラクター チェーン

C# では、コンストラクターを連鎖させたい場合は、これを行います...

Boo の同等の構文は何ですか?

0 投票する
2 に答える
467 参照

c# - これは、コンストラクター チェーンを使用する良い方法ですか、それとも悪い方法ですか? (...テストを可能にするため)

ここでクラス コンストラクターをチェーン化する動機は、アプリケーションがメインストリームで使用する既定のコンストラクターと、モックとスタブを挿入できるようにするためです。

":this(...)" 呼び出しで少し醜い「新しい」ものに見えるだけで、デフォルトのコンストラクターからパラメーター化されたコンストラクターを呼び出す直感に反します。他の人はここで何をするのだろうか?

(参考までに -> SystemWrapper )

0 投票する
7 に答える
727 参照

c# - :this()コンストラクターとして

私は一般診療をよりよく理解しようとしています...具体的にはコンストラクターでthis()を導出します。コードが少ないことは理解していますが、読みにくいと思います。このようにすることは一般的/良い習慣ですか?それとも、それを具体的に処理する2番目のコンストラクターを作成する方がよいでしょうか。

また

任意の入力をいただければ幸いです

0 投票する
6 に答える
4517 参照

delphi - Delphi:祖先コンストラクターを非表示にする方法は?

更新:最初に受け入れられた回答では回答されない、より単純な例で質問を根絶しました

次のクラスとその祖先が与えられます。

現在TCellPhone、3つのコンストラクターが表示されています。

  • カップ:整数
  • カップ:整数; ティーポット:文字列
  • ティーポット:文字列=''

TCellPhone祖先コンストラクター(Teapot: string = '')が表示されず、宣言されたコンストラクターのみが残るようにするにはどうすればよいですか?

  • カップ:整数
  • カップ:整数; ティーポット:文字列

:通常、子孫コンストラクターを持つという単純な行為は、祖先を非表示にします。

  • カップ:整数

また、祖先コンストラクターと子孫の両方を保持したい場合は、子孫をoverload:としてマークします。

  • カップ:整数
  • ティーポット:文字列=''

この質問のサンプルコードでは、Delphiが私のoverloadキーワードを間違えています。

それを考える:

  • コンストラクターを祖先でオーバーロードしたい、
  • 本当に兄弟でオーバーロードしたいとき

祖先コンストラクターを非表示にするにはどうすればよいですか?

注:現在定義されているDelphi言語を使用して、祖先の非仮想コンストラクターを非表示にすることは不可能な場合があります。「不可能」は有効な答えです。


試行された回答(失敗)

子孫コンストラクターに次のマークを付けてreintroduceました(機能するまでキーワードをランダムに追加するモードにフォールバックします):

しかし、それは機能しませんでした。3つのコンストラクターはすべて表示されたままです。:(


元の質問

コンストラクターが見たくないクラスの子孫であるオブジェクトがあります。

注:これは架空の例です。現実の世界と同様に、祖先オブジェクトは既存のコードを壊さずに変更することはできません。

今、誰かが使用しているとき、私は彼らがコンストラクターを見るTiPhoneことができることさえ望んでいません:TEniac

さらに悪いことに、彼らがそのコンストラクターを呼び出すと、私のコンストラクターを完全に見逃し、その間にすべてが行われます。間違ったコンストラクターを呼び出すのは非常に簡単です。それらはすべてIDEコード補完に表示され、コンパイルされます。

そして、それらは完全に無効なオブジェクトを取得します。

TCellPhoneこれらのコンストラクターで例外をスローするように変更できます。

しかし、開発者は、顧客がいつかエラーを見つけて数十億ドルの罰金を科すまで、間違ったコンストラクターを呼び出していることに気づきません。実際、私はどこでも間違ったコンストラクターを呼び出そうとしていますが、Delphiに教えてもらう方法がわかりません!

0 投票する
4 に答える
19096 参照

delphi - Delphi:コンストラクターを理解する

私は理解しようとしています

  • バーチャル
  • オーバーライド
  • 過負荷
  • 再導入

オブジェクトコンストラクターに適用された場合。コンパイラがシャットダウンするまで、ランダムにキーワードを追加するたびに(Delphiで12年間開発した後)、ランダムに試すのではなく、自分が何をしているのかを知りたいと思います。

架空のオブジェクトのセットが与えられた場合:

私が彼らに振る舞わせたい方法はおそらく宣言から明らかですが:

  • TComputer単純なコンストラクターがあり、子孫はそれをオーバーライドできます
  • TCellPhone代替コンストラクターがあり、子孫はそれをオーバーライドできます
  • TiPhone両方のコンストラクターをオーバーライドし、それぞれの継承バージョンを呼び出します

これで、そのコードはコンパイルされません。なぜうまくいかないのか理解したい。また、コンストラクターをオーバーライドする適切な方法を理解したいと思います。または、コンストラクターをオーバーライドすることはできませんか?それとも、コンストラクターをオーバーライドすることは完全に受け入れられますか?おそらく、複数のコンストラクターを持つべきではありません。おそらく、複数のコンストラクターを持つことは完全に許容されます。

理由を理解したい。そうすれば、それを修正することは明らかです。

も参照してください

編集:私はまた、、、、の順序でいくつかの推論を得ることを探してvirtualいます。キーワードのすべての組み合わせを試すと、組み合わせの数が爆発的に増えるためです。overrideoverloadreintroduce

  • バーチャル; 過負荷;
  • バーチャル; オーバーライド;
  • オーバーライド; 過負荷;
  • オーバーライド; バーチャル;
  • バーチャル; オーバーライド; 過負荷;
  • バーチャル; 過負荷; オーバーライド;
  • 過負荷; バーチャル; オーバーライド;
  • オーバーライド; バーチャル; 過負荷;
  • オーバーライド; 過負荷; バーチャル;
  • 過負荷; オーバーライド; バーチャル;

編集2: 「オブジェクト階層は可能ですか? 」から始めるべきだと思います。そうでない場合は、なぜですか?たとえば、祖先からコンストラクターを持つことは根本的に間違っていますか?

TCellPhone今では2つのコンストラクターがあると思います。しかし、Delphiでキーワードの組み合わせを見つけて、それが有効なことだと思わせることができません。私はここに2つのコンストラクターを持つことができると考えるのは根本的に間違っていTCellPhoneますか?


注:この線より下のすべてが質問に答えるために厳密に必要なわけではありませんが、それは私の考えを説明するのに役立ちます。おそらく、私の思考プロセスに基づいて、すべてを明確にするために私が欠けている基本的な部分を見ることができます。

現在、これらの宣言はコンパイルされません。


だから最初に私は修正しようとしますTCellPhone。キーワードをランダムに追加することから始めます(それは私が望まない他のコンストラクターを隠すので、overload私は望まないことを知っています):reintroduce

しかし、それは失敗します:Field definition not allowed after methods or properties

メソッドまたはプロパティの後にフィールドがない場合でも、キーワードvirtualoverloadキーワードの順序を逆にすると、Delphiがシャットダウンすることを経験から知っています。

しかし、それでもエラーが発生します。

メソッド「作成」は、基本タイプ「TComputer」の仮想メソッドを非表示にします

だから私は両方のキーワードを削除してみます:

しかし、それでもエラーが発生します。

メソッド「作成」は、基本タイプ「TComputer」の仮想メソッドを非表示にします

だから私は今試してみることに自分自身を辞任しますreintroduce

そして今、TCellPhoneはコンパイルされますが、それはTiPhoneにとって事態をさらに悪化させました。

どちらもオーバーライドできないと不平を言っているので、overrideキーワードを削除します。

しかし、2番目の作成では、オーバーロードでマークする必要があると言っています。これは、オーバーロードとしてマークする必要があります(実際、オーバーロードとしてマークするのは、そうでない場合に何が起こるかを知っているためです)。

このセクションではすべてが良好interfaceです。残念ながら、私の実装は機能しません。TiPhoneの単一パラメーターコンストラクターは、継承されたコンストラクターを呼び出すことができません。

0 投票する
4 に答える
2893 参照

delphi - Delphi:子孫に別のコンストラクターを追加するにはどうすればよいですか?

更新:私が最初に持っていた例は、ちょっと複雑でした。これは、1つのコードブロックですべてを説明する簡単な8行の例です。以下はコンパイルされないため、警告が表示されます。

注:この質問は、Delphiのコンストラクターの微妙さに関する私の進行中の一連の質問のパート3です。

元の質問

既存のクラスにコンストラクターを追加するにはどうすればよいですか?

架空の例を挙げましょう(つまり、ここでSOエディターに入力しているので、コンパイルされる場合とされない場合があります)。

TXHTMLStreamさらに、通常の使用では、使用する前に多くの繰り返しコードを実行する必要があると想定します。

ボイラープレートのセットアップコードをすべて単純化するコンストラクターを作成したいとします。

これにより、オブジェクトの使用が簡単になります。

今を除いて、Delphiは私の新しいコンストラクターが古いコンストラクターを隠していると不平を言います。

メソッド「作成」は、基本タイプ「TXMLStream」の仮想メソッドを非表示にします

私は確かに祖先の作成を隠すつもりはありませんでした-は両方が欲しいです。

祖先コンストラクターを保持したまま、子孫クラスに(異なるシグネチャを持つ)コンストラクターを追加して、引き続き使用できるようにするにはどうすればよいですか?

0 投票する
4 に答える
3918 参照

delphi - Delphi:いつ非表示の祖先を再導入し、いつそれらを表示しますか?

今日最近Stackoverflowで私はそれを学びました:

私はそれをすべて理解しようとしてきたので、コンストラクターを扱う私の主な質問をサポートする、別の非常に具体的な質問があります。


更新:質問全体を置き換えました:

TCellPhoneを構築する場合、3つのコンストラクターを使用できます。

  • カップ:整数
  • カップ:整数; ティーポット:文字列
  • [ティーポット:文字列='']

質問:なぜconstructor(Teapot: string='')隠されていないのですか?


今私は3番目の子孫を追加しました:

TiPhone 4つのコンストラクターを作成する場合は、次のようにします。

  • カップ:整数
  • カップ:整数
  • カップ:整数; ティーポット:文字列
  • [ティーポット:文字列='']

なぜコンストラクターが4つあるのですか?既存の3つのうちの1つを上書きしました。編集:これはコードインサイトのバグである可能性があり、4つ表示されますが、2つが同じである場合、どうすれば呼び出すことができますか?


元のコードを再度使用する:

TCellPhone3つのコンストラクターがあることはすでに知られています。

  • カップ:整数
  • カップ:整数; ティーポット:文字列
  • [ティーポット:文字列='']

TCellPhoneの宣言を変更して祖先コンストラクターを非表示にするにはどうすればよいですか?たとえば、次のようになります。

コンストラクターは2つだけです。

  • カップ:整数
  • カップ:整数; ティーポット:文字列

ここで、がreintroduce非仮想の祖先を非表示にするために使用される場合について説明します。前のケースでは、TiPhoneコンストラクターが4つあります(理想的には2つだけでTComputer、祖先が何らかの形で隠されています)。しかし、私が修正できない場合でも、私は1つだけを持つようにTComputer変更することができます:TiPhone

現在TiPhone、コンストラクターは1つだけです。

  • カップ:整数

Reintroduceは通常、仮想祖先の非表示に関する警告を抑制するためにのみ使用されます。この場合:

仮想ではありません-それでも、reintroduceを使用して非表示にすることができます。


しかし、私が別のオーバーロードを追加した場合TiPhone

その後、突然(以前は隠されていた)祖先が戻ってきます:

  • TiPhone.Create(7);
  • TiPhone.Create('ピンク');
  • TiPhone.Create(7、'ピンク');
  • TiPhone.Create();

ご覧のとおり、私はの論理を理解するのに苦労しています

  • 何かが隠されているとき
  • 何かを隠す方法
  • 何かが表示されたとき
  • 何かを示す方法
0 投票する
1 に答える
2158 参照

delphi - Delphi:オーバーライドされた仮想コンストラクタの子孫がオーバーロードによって呼び出されていない

Delphiのコンストラクタに関する一連の質問のもう1つ。

仮想コンストラクターを持つ基本クラスがあります。

コンストラクターは、誰かが呼び出す必要があるときのために仮想です

コンストラクターはoverridden子孫にあります:

WhereTCellPhoneTiPhone子孫はそれぞれ独自の初期化を行う機会があります(読みやすさのために含まれていないメンバーの)。

しかし今、私はオーバーロードされたコンストラクターをいくつかの祖先に追加します:

TCellPhoneの代替コンストラクターは、他の仮想コンストラクターを呼び出すため、常に適切なオーバーライド動作を取得します。

問題は、子孫のオーバーライドされたコンストラクターが呼び出されないことです。呼び出しの実際のスタックトレースチェーンは次のとおりです。

仮想であるへの兄弟呼び出しは、次TCellPhone.Create(int)の子孫のオーバーライドされたメソッドを呼び出す必要がありますTiPhone

したがって、兄弟仮想コンストラクターを使用しようとすると、Delphiが期待どおりに機能しないようです。

では、あるコンストラクターが別のコンストラクターを使用するのは悪い考えですか?オーバーロードされたコンストラクターのコードが相互のコピーアンドペーストバージョンであるという設計意図はありますか?

.NETで、いくつかのコンストラクターが相互にチェーンしていることに気付きました。

これは、次の場合にのみ問題になるようです。

  • コンストラクターは仮想です
  • コンストラクターをオーバーロードします

あるコンストラクターに別のコンストラクターをオーバーロードさせることはできないというルールはありますか?

0 投票する
3 に答える
368 参照

delphi - コンストラクターの可視性について

以下に 2 つの単純なクラスを示します。最初はどちらもキーワード (virtual、overload、override、reintroduce) を持っていません。

上記の定義を少し短いものとして表します。

また、構築時には、コンストラクター ( , )TCellPhoneが 1 つしかありません。これは、祖先コンストラクターが非表示になっているためです。i の可視コンストラクターを次のように示します。intstringTCellPhone

  • ティーポット: 整数; ハンドル:紐

ここで質問ですが、最初の 3 つのケースは理にかなっていますが、4 番目のケースは意味がありません。

1. 祖先コンストラクターは子孫によって隠されています。

  • Teapot: Integer; Handle: string

これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。

2. 祖先の仮想コンストラクターは子孫によって隠されています。

  • Teapot: Integer; Handle: string

これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。

注:先祖は仮想であるため、Delphi は、仮想先祖を非表示にしていることを警告します (前の静的コンストラクターを非表示にする例: 誰も気にしないので、警告はありません)。reintroduceを追加することで、警告を抑制することができます (「ええええええ、私は仮想コンストラクターを隠しています。そう するつもりでした」という意味です)。

3. オーバーロードのため、祖先コンストラクターが子孫に隠されていません:

  • Teapot: Integer; Handle: string
  • Teapot: Integer

子孫コンストラクターは祖先のオーバーロードであるため、これは理にかなっています。そのため、両方を存在させることができます。祖先コンストラクターは隠されていません。

4. オーバーロードのため、仮想先祖コンストラクターが子孫に隠されていません -それでも警告が表示されます:

これは意味をなさないケースです:

  • Teapot: Integer; Handle: string
  • Teapot: Integer

    メソッド 'Create' は、基本型 'TComputer' の仮想メソッドを非表示にします

これはほとんど意味がありません。先祖が隠れていないだけでなく、子孫が過負荷になっています。文句を言うべきでもありません

何を与える?

0 投票する
2 に答える
622 参照

javascript - JavaScript でのコンストラクターの連鎖

JavaScript である種のクラス階層を実装しようとしています。プロトタイプ チェーンは理解できたと思いますが、コンストラクター チェーンを整理する必要があります。David Flanagan's Definitive Guideに従って、私は書きました

whereBaseClass()は C++ で記述された私のネイティブ関数です (私はQtScriptを使用しています)。私の問題はBaseClass()、コンストラクターとしてではなく、関数として呼び出されることです。

BaseClass()常にコンストラクターとして動作するようにコーディングできますが、呼び出されます。しかし、いつの日かユーザーの 1 人が忘れnew て書き込んでしまうのではないかと心配しています。

このような状況ではBaseClass()、グローバル オブジェクトを初期化するよりも賢明なことをしたいと思います。例えば:

しかし、コンストラクターの連鎖は失敗します!

コンストラクターをチェーンして、BaseClass() 実際にコンストラクターとして呼び出す方法はありますか? それとも、決して忘れないようにユーザーを教育する必要がありnewますか? 現在、上記のテストを次のように置き換えたいと思っています。

しかし、これを処理するためのよりクリーンな方法があるのだろうか。

ありがとう!