エラー、バグ、質問 - ページ 2357 1...235023512352235323542355235623572358235923602361236223632364...3185 新しいコメント Ilyas 2018.12.24 14:32 #23561 Ilya Malev:詳しい回答ありがとうございました!しかし、ちょっと理屈がわかりません。 1) なぜコンパイラはB* b1=a 構文をA::A(const A&) コピー演算子の呼び出しと認識するのか (B::B(const A&) 呼び出しではなく、= 演算子の左側にあるのは B クラスだからです)。 2) なぜ、コンパイラは「コピーコンストラクタがありません」という警告を出さなかったのでしょうか? 3) 存在しないオブジェクトに対して「単純な」メソッド呼び出しが許される理由 (一方で A::f() を直接呼び出そうとすると「静的メソッド 呼び出しではありません」というコンパイルエラーが発生します)1) これは明らかなエラーなので、とにかく修正すると書きました 2) コピーコンストラクタは、ユーザーによって宣言されていない場合、コンパイラによって生成されます。 3)質問がよくわからない。 議論の文脈から ポインタにアクセスがない場合、ポインタを「参照解除」するかどうかについては、長い間議論することができましたか? デリファレンス操作(ハンドルから実際のポインタを取得する)は「内部」(カスタムではない)であり、(それがない場合と比較して)高価なコードである。 ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか? そのままであれば、ポインターのアクセスがなければ、デリファレンス操作はオプティマイザで削除されます。 Ilyas 2018.12.24 14:35 #23562 Ilya Malev:4) また、なぜコンパイラは「単純な」仮想メソッド呼び出しをまったく許可しないのでしょうか?仮想性は、オブジェクトのデータの有無に依存すべきではないと思うのですが......。問題を混同していますね。 コールデバーチャライズは、オブジェクトのフィールドの有無とは関係ない別の最適化方法です。 Alexey Navoykov 2018.12.24 14:44 #23563 Ilyas: 2) コピーコンストラクタは、ユーザーが宣言しない限り、コンパイラによって生成されます。 左側にBオブジェクトがあるのに、なぜA::A(A&)コンストラクタが呼ばれる(生成される)のか? これはOOPの原則に反している Ilya Malev 2018.12.24 14:47 #23564 Alexey Navoykov: 左側にオブジェクトBがあるのに、なぜコンストラクタA::A()が呼ばれるのでしょうか?なぜなら、µlでは、左側にポインター、右側に「オブジェクト」があるとき、演算子=、=、!=、&、|は常にこのように振る舞うからです。そして同時に、これらの演算子はポインタに対してオーバーロードすることができません。 そこで、このバグを修正する際には、上記の演算子をダイナミックオブジェクトに対してオーバーロード可能にすることをお願いします。 Dima Tutov 2018.12.24 14:47 #23565 メタトレーダー4が動かなくなった、起動時に1秒くらい動いて、左上にワンクリックの取引画面が出て(Buy/Sell)、アプリが終了してしまう。 何か解決方法があれば教えてください。 よろしくお願いします。 Alexey Navoykov 2018.12.24 14:51 #23566 Ilya Malev:なぜなら、ポインタが左にあり、「オブジェクト」タイプが右にあるとき、µl では常にこのように演算子 =, ==, !=, !&, &&, || が振舞うからです。 ポインターと何の関係があるんだ? もうここで 話したろ?ここでは、ポインタがなくても同じように動作します。 Ilyas 2018.12.24 14:55 #23567 Alexey Navoykov: 左側にオブジェクトBがあるのに、なぜA::A(A&)コンストラクタが呼ばれる(生成される)のか? これはOOPの原則に反している私も完全に同意見で、これは訂正される誤りであることをすでに書きました。 この場合、コンパイラはオブジェクトの構築時に行うべきでない継承時の適切なオーバーロードを拾っているのです。 Ilya Malev 2018.12.24 14:56 #23568 イリヤスポインタにアクセスがない場合、「デリファレンス」を行うかどうかについては、長い間議論することができます。デリファレンス操作(ハンドルから実ポインタを得る)は、「内部」(カスタムではない)かつ「高価」な(持たない場合に比べて)コードです。 ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか? なぜなら、仮想メソッドのリストはオブジェクトの情報の一部であり、データそのものに劣らず重要であり、仮想メソッドへのアクセスはポインタアクセスであるからです。例えば、私の例で書くと A* aa=a; B* b1=a; b1=aa; b1.f(); このコードはAから「コピー」され、A*から参照されたA*オブジェクトの代入を明示的に参照していますが、私は再びB::f()を取得します。これは、「間違った」コピーコンストラクタを呼び出すことよりも深い状況です。しかし、仮にそのオブジェクトが仮想メソッドを持っていなかったとしても、アクセスする際にポインタの有効性をチェックするべきだったのです。 A100 2018.12.24 14:57 #23569 Alexey Navoykov: 左側に B オブジェクトがあるのに、なぜA::A(A&) コンストラクタが呼ばれる(生成される)のか? これは OOP の原則に反しています。本当にそこに何か呼び物があるのか?x32で確認しました。 class A { public: A() { Print(__FUNCSIG__); } A( const A& ) { Print(__FUNCSIG__); } } a; class B : public A { public: B() { Print(__FUNCSIG__); } B( const B& ) { Print(__FUNCSIG__); } } *b = a; void OnStart() {} 結果:A::A() といった具合です。 Ilyas 2018.12.24 15:04 #23570 A100:本当にそこに何か呼び物があるのか?x32で確認しました。 結果:A::A() といった具合です。というわけで、ジェネレータとオプティマイザのダンプをチェックして、I'sを点数化することにしました。 1...235023512352235323542355235623572358235923602361236223632364...3185 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
詳しい回答ありがとうございました!しかし、ちょっと理屈がわかりません。
1) なぜコンパイラはB* b1=a 構文をA::A(const A&) コピー演算子の呼び出しと認識するのか (B::B(const A&) 呼び出しではなく、= 演算子の左側にあるのは B クラスだからです)。
2) なぜ、コンパイラは「コピーコンストラクタがありません」という警告を出さなかったのでしょうか?
3) 存在しないオブジェクトに対して「単純な」メソッド呼び出しが許される理由 (一方で A::f() を直接呼び出そうとすると「静的メソッド 呼び出しではありません」というコンパイルエラーが発生します)
1) これは明らかなエラーなので、とにかく修正すると書きました
2) コピーコンストラクタは、ユーザーによって宣言されていない場合、コンパイラによって生成されます。
3)質問がよくわからない。
議論の文脈から
ポインタにアクセスがない場合、ポインタを「参照解除」するかどうかについては、長い間議論することができましたか?
デリファレンス操作(ハンドルから実際のポインタを取得する)は「内部」(カスタムではない)であり、(それがない場合と比較して)高価なコードである。
ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか?
そのままであれば、ポインターのアクセスがなければ、デリファレンス操作はオプティマイザで削除されます。
4) また、なぜコンパイラは「単純な」仮想メソッド呼び出しをまったく許可しないのでしょうか?仮想性は、オブジェクトのデータの有無に依存すべきではないと思うのですが......。
問題を混同していますね。
コールデバーチャライズは、オブジェクトのフィールドの有無とは関係ない別の最適化方法です。
2) コピーコンストラクタは、ユーザーが宣言しない限り、コンパイラによって生成されます。
左側にオブジェクトBがあるのに、なぜコンストラクタA::A()が呼ばれるのでしょうか?
なぜなら、µlでは、左側にポインター、右側に「オブジェクト」があるとき、演算子=、=、!=、&、|は常にこのように振る舞うからです。そして同時に、これらの演算子はポインタに対してオーバーロードすることができません。
そこで、このバグを修正する際には、上記の演算子をダイナミックオブジェクトに対してオーバーロード可能にすることをお願いします。
何か解決方法があれば教えてください。
よろしくお願いします。
なぜなら、ポインタが左にあり、「オブジェクト」タイプが右にあるとき、µl では常にこのように演算子 =, ==, !=, !&, &&, || が振舞うからです。
左側にオブジェクトBがあるのに、なぜA::A(A&)コンストラクタが呼ばれる(生成される)のか? これはOOPの原則に反している
私も完全に同意見で、これは訂正される誤りであることをすでに書きました。
この場合、コンパイラはオブジェクトの構築時に行うべきでない継承時の適切なオーバーロードを拾っているのです。
ポインタにアクセスがない場合、「デリファレンス」を行うかどうかについては、長い間議論することができます。
デリファレンス操作(ハンドルから実ポインタを得る)は、「内部」(カスタムではない)かつ「高価」な(持たない場合に比べて)コードです。
ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか?
なぜなら、仮想メソッドのリストはオブジェクトの情報の一部であり、データそのものに劣らず重要であり、仮想メソッドへのアクセスはポインタアクセスであるからです。例えば、私の例で書くと
このコードはAから「コピー」され、A*から参照されたA*オブジェクトの代入を明示的に参照していますが、私は再びB::f()を取得します。これは、「間違った」コピーコンストラクタを呼び出すことよりも深い状況です。しかし、仮にそのオブジェクトが仮想メソッドを持っていなかったとしても、アクセスする際にポインタの有効性をチェックするべきだったのです。
左側に B オブジェクトがあるのに、なぜA::A(A&) コンストラクタが呼ばれる(生成される)のか? これは OOP の原則に反しています。
本当にそこに何か呼び物があるのか?x32で確認しました。
結果:A::A()
といった具合です。
本当にそこに何か呼び物があるのか?x32で確認しました。
結果:A::A()
といった具合です。
というわけで、ジェネレータとオプティマイザのダンプをチェックして、I'sを点数化することにしました。