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

 
A100:

in C++: A::f()

このコードには何が書かれているのでしょうか?

((A*)&b).f();
 
fxsaber:

このコードには何が書かれているのでしょうか?

同じです。

 
Ilya Malev:

同じことです。

をMQLとして(C++形式に変換されることを前提に)作成します。しかし、自分で確認することもできたはず
 
A100:
それとMQL(C++形式に変換されることが前提)。しかし、自分で確認することもできたはず

確認しました。


 
Ilya Malev:

確認しました。

チェックの仕方が間違っているのでは?

B*b1=a;

MQLのこのようなエントリは、オブジェクトaをポインタb1で指定されたオブジェクトにコピーすることを意味します。 一般的には、もちろん、コンパイルしてはいけません。

また、オブジェクトとポインタを混同しないように、ポインタにはpという接頭辞をつけた方がよいでしょう

 
Ilya Malev:

確認しました。

このような誤った行動で職質されることのないようにお願いします。

ここで2つの問題(?)があります。

  1. B *b1=a - 明示的なエラー。コンパイラはこの構成を A::A(const A &) コピー演算子の呼び出しと見なします。

  2. 最初のケースでは,オプティマイザは A::A(const A &) が空であること,メンバがないこと,「ポインタ」によるアクセスがないことを検出しました(実際,コピー演算子を呼び出すコードはなく,すべてが切り取られています)。
    仮想B::f()はオーバーロードされていないので、仮想呼び出しの代わりに単純な呼び出しとなり、B::f()にはメンバーアドレスがないので、「ポインタ」によるアクセスもカットされました。

    2番目のケースでは、A::f()は仮想呼び出しが試みられ、「ポインタ」によるアクセスはあるが、a1オブジェクトはない。これは、A *a1=bに対して空のコピーコンストラクタ A::A(const A &) も呼び出されたからだ
 
Ilyas:

このような誤った行動で銀行を利用しないようにしてください。

ここで2つの問題(?)があります。

この誤動作を直してほしいのですが?(コンパイルエラーを 出す) 誤ってこのようなエラーを出す可能性があり、コンパイラは何ら反応しないため。

 
Alexey Navoykov:

この誤動作を直してほしいのですが?なぜなら、偶然にそのようなエラーを起こす可能性があり、コンパイラは何の反応も示さないからです。

はい、修正します。

空のクラスだけが動作コードを取得するため、優先度は低く設定されている

 
Ilyas:

このような誤った行動で銀行を利用しないようにしてください。

ここで2つの問題(?)があります。

  1. B *b1=a - 明らかなエラー。コンパイラはこの構文をコピー演算子 A::A(const A &) の呼び出しとして認識する。

  2. 最初のケースでは,オプティマイザは A::A(const A &) が空であり,メンバがなく,「ポインタ」によるアクセスもできないと判断した(実際,コピー演算子を呼ぶコードはなく,すべてが切り捨てられた)。
    仮想B::f()はオーバーロードされないので、仮想呼び出しの代わりに単純な呼び出しとなり、B::f()はメンバーアドレスを持たないので、「ポインタ」によるアクセスもカットされました。

    2番目のケースでは、A::f()は仮想呼び出しが試みられ、「ポインタ」によるアクセスはあるが、a1オブジェクトはない。これは、A *a1=bに対して空のコピーコンストラクタ A::A(const A &) も呼び出されたからだ

詳しいご回答ありがとうございます。ただ、ちょっと理屈がわからないのです。

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

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

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

4) また、なぜコンパイラは「単純な」仮想メソッド呼び出しをまったく許可しないのでしょうか?私の考えでは、仮想性はオブジェクトのデータの有無に依存してはいけません。

 
Ilya Malev:

1) なぜコンパイラはB* b1=a をコピー演算子A::A(const A&) の呼び出しと見なすのでしょうか, (代わりにB::B(const A&) を呼び出し、 operator= の左がクラス B であるため)。

これはカプセル化の原則に反するものです。 C++では、このようなことは自然にコンパイルされず、明示的な変換が必要です。 また、古いMQLのビルドでは、このようなことはできませんでした。