エラー、バグ、質問 - ページ 2357

 
Ilya Malev:

詳しい回答ありがとうございました!しかし、ちょっと理屈がわかりません。

1) なぜコンパイラはB* b1=a 構文をA::A(const A&) コピー演算子の呼び出しと認識するのか (B::B(const A&) 呼び出しではなく、= 演算子の左側にあるのは B クラスだからです)。

2) なぜ、コンパイラは「コピーコンストラクタがありません」という警告を出さなかったのでしょうか?

3) 存在しないオブジェクトに対して「単純な」メソッド呼び出しが許される理由 (一方で A::f() を直接呼び出そうとすると「静的メソッド 呼び出しではありません」というコンパイルエラーが発生します)

1) これは明らかなエラーなので、とにかく修正すると書きました

2) コピーコンストラクタは、ユーザーによって宣言されていない場合、コンパイラによって生成されます。

3)質問がよくわからない。
議論の文脈から
ポインタにアクセスがない場合、ポインタを「参照解除」するかどうかについては、長い間議論することができましたか?
デリファレンス操作(ハンドルから実際のポインタを取得する)は「内部」(カスタムではない)であり、(それがない場合と比較して)高価なコードである。
ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか?
そのままであれば、ポインターのアクセスがなければ、デリファレンス操作はオプティマイザで削除されます。

 
Ilya Malev:

4) また、なぜコンパイラは「単純な」仮想メソッド呼び出しをまったく許可しないのでしょうか?仮想性は、オブジェクトのデータの有無に依存すべきではないと思うのですが......。

問題を混同していますね。

コールデバーチャライズは、オブジェクトのフィールドの有無とは関係ない別の最適化方法です。

 
Ilyas:

2) コピーコンストラクタは、ユーザーが宣言しない限り、コンパイラによって生成されます。

左側にBオブジェクトがあるのに、なぜA::A(A&)コンストラクタが呼ばれる(生成される)のか? これはOOPの原則に反している
 
Alexey Navoykov:
左側にオブジェクトBがあるのに、なぜコンストラクタA::A()が呼ばれるのでしょうか?

なぜなら、µlでは、左側にポインター、右側に「オブジェクト」があるとき、演算子=、=、!=、&、|は常にこのように振る舞うからです。そして同時に、これらの演算子はポインタに対してオーバーロードすることができません。

そこで、このバグを修正する際には、上記の演算子をダイナミックオブジェクトに対してオーバーロード可能にすることをお願いします。

 
メタトレーダー4が動かなくなった、起動時に1秒くらい動いて、左上にワンクリックの取引画面が出て(Buy/Sell)、アプリが終了してしまう。
何か解決方法があれば教えてください。
よろしくお願いします。
 
Ilya Malev:

なぜなら、ポインタが左にあり、「オブジェクト」タイプが右にあるとき、µl では常にこのように演算子 =, ==, !=, !&, &&, || が振舞うからです。

ポインターと何の関係があるんだ? もうここで 話したろ?ここでは、ポインタがなくても同じように動作します。
 
Alexey Navoykov:
左側にオブジェクトBがあるのに、なぜA::A(A&)コンストラクタが呼ばれる(生成される)のか? これはOOPの原則に反している

私も完全に同意見で、これは訂正される誤りであることをすでに書きました。

この場合、コンパイラはオブジェクトの構築時に行うべきでない継承時の適切なオーバーロードを拾っているのです。

 
イリヤス

ポインタにアクセスがない場合、「デリファレンス」を行うかどうかについては、長い間議論することができます。

デリファレンス操作(ハンドルから実ポインタを得る)は、「内部」(カスタムではない)かつ「高価」な(持たない場合に比べて)コードです。
ポインタへのアクセスがないのに、なぜデリフェレンシングを行うのですか?

なぜなら、仮想メソッドのリストはオブジェクトの情報の一部であり、データそのものに劣らず重要であり、仮想メソッドへのアクセスはポインタアクセスであるからです。例えば、私の例で書くと

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

このコードはAから「コピー」され、A*から参照されたA*オブジェクトの代入を明示的に参照していますが、私は再びB::f()を取得します。これは、「間違った」コピーコンストラクタを呼び出すことよりも深い状況です。しかし、仮にそのオブジェクトが仮想メソッドを持っていなかったとしても、アクセスする際にポインタの有効性をチェックするべきだったのです。

 
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()
といった具合です。

 
A100:

本当にそこに何か呼び物があるのか?x32で確認しました。

結果:A::A()
といった具合です。

というわけで、ジェネレータとオプティマイザのダンプをチェックして、I'sを点数化することにしました。