MQL5 コンパイラはクラスとそのポインタを区別しない - ページ 12

 
Georgiy Merts:

この場合、ブロックの終了時に変数を削除しなければならないのは明らかです。

newで作成したオブジェクトの話です。

C#規格で規定されている。"構造体などの値型オブジェクトもクラスなどの参照型オブジェクトも自動的に破棄されるが、値型オブジェクトはそれを含むコンテキストが破壊されたときに破棄され、参照型オブジェクトはそのオブジェクトへの最後の参照が削除された後、ゴミ収集者によって無期限に破棄 される。"

ここで、この「予測不可能な時間」が嫌なのです。もっとも、私自身がオブジェクトを作成したクラスのデストラクタでオブジェクトを削除するよりも、ゴミ回収業者の方がはるかに効率的にオブジェクトを削除できることは認めます。

論理的には、誰も参照していないということは、誰もそのオブジェクトを必要としていないということであり、次のゴミ収集時に削除されることになる。時間は予測できませんが、GCに頼んですぐに作ってもらうことは可能です。しかし、これも要望であって、注文ではない )))

 
Georgiy Merts:

ゴミ収集機がライブオブジェクトやポインタを削除するとは言っていない。外そうと思えば外せると言っているのです。

シャープには、ゴミ回収業者によって削除されないように保護する機能があります。

https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.interopservices.gchandle.alloc?view=netcore-2.0

// for standalone object
public byte[] RawSerialize(object objAny)
{
int rawsize = Marshal.SizeOf(objAny);
byte[] m_obj = new byte[rawsize];

        GCHandle hObj = GCHandle.Alloc(m_obj, GCHandleType.Pinned);

        Marshal.StructureToPtr(objAny, hObj.AddrOfPinnedObject(), false);
        hObj.Free();

return (m_obj);
}
GCHandle.Alloc Method (System.Runtime.InteropServices)
GCHandle.Alloc Method (System.Runtime.InteropServices)
  • dotnet-bot
  • docs.microsoft.com
Выделяет дескриптор для указанного объекта.Allocates a handle for the specified object.
 
Alexey Navoykov:

そして今、あなたは必死で知らなかったと言い訳をしようとしている ;)

すぐに導入しても、数カ月後に導入しても同じこと。 言わなきゃわからないでしょ(笑)。

恥ずかしくて焼け石に水ですが、最近まで&&のことは、どこかのfxsaberで見るまで知りませんでした。そうでなければGetPointerを 使う。

しかし、9月のどこかで、オブジェクトを使ったオーバーロードの可能性がないことに注目し、自分で解決しようとしたところ、そのような可能性はないと書いてきた人がいました。そして今回、その存在が判明したわけですが、具体的にいつ登場したのか(なぜヘルプにないのか)気になります。

 
SemenTalonov:

おそらく、C#のように「マネージドコード」にポインターを持たず、単純なbool int doubleなどの型も すべてオブジェクトにする方向に行くのだろう。

これはいいことなのだが、端末言語の概念を完全に変えることになるので、このような方向で何かを変えるということはまずないだろう。

セメン・タロノフ

まさにIMHOによれば、何を扱っているのか(オブジェクトか、それへのポインタか)を忘れないことが必要です。

忘れないようにするためには、オブジェクトを使うときとポインターを使うときを最初にはっきり決めておくことです(理想はオブジェクトを使わず、常にポインターを使うことです)。

そして、そのために毎回余計な文字を書くのも(特にわざわざ括弧をつけるのも)バカらしい。

また、この場合は、オブジェクトではなく、その非オブジェクトフィールドに対する代入操作であるため、原理的にエラーの可能性はありません(このような操作におけるポインタ型は問題ではありません)。

 
Ilya Malev:

このことを忘れないように、オブジェクトを使うときとポインターを使うときを最初にきちんと決めておく必要があります(理想は、オブジェクトは使わず、ポインターは常に使うことです)。

久しぶり(1〜2年ぶり)に自分のコードを開いて、「微妙なところにコメントを残していなかった」「オブジェクトとポインタの区別がつかない」と自分を叱ると、完敗のような気がします。また、オートオブジェクトの使用を拒否することにも賛成できません。これを使えば、コードがコンパクトになり、オブジェクトが陳腐化した後の運命も気にならなくなる。それに、そのようなオブジェクトの寿命はあらかじめコンパイラに分かっているはずなので、コンパイラは動的生成の場合よりも最適化されたコードを提供できるはずです。

イリヤ・マレフ

そのためにいちいち文字を書き足すのも(特にわざわざ括弧をつけるのも)バカバカしいですしね。

さらに、あなたの言うケースでは、代入操作はオブジェクトに対してではなく、その非オブジェクトフィールドに対して行われているので、基本的にエラーの可能性はありません(このような操作におけるポインタの型は重要ではありません)。

この無意味さは、MQLでは、ポインタによるオブジェクトへのアクセスを表す方法が他にないことに由来する。C/C++では、もちろん、もっと饒舌になるのだろう。

pA->iValue

矢印がないのは、もともと「*」と同じ理由だろう(不明)。Qtでは(おそらくVSでも)、オブジェクトがポインタでアクセスされた場合、エディタは自動的に'.を'->'に置き換えます。MQが望めば、そのような機能をエディタに追加できることは間違いないでしょう。結局のところ、この例ではポインタを扱っていることを示すのは、名前に 'p' という接頭語がついていることだけです。それは、忘れていないからに他なりません。みんながそう『機転を利かせる』ならそれでいいのですが...))

つまり、潜在的に危険なコード断片は明示的にマークされるべきなのです。覚えている必要はない、見て いればいいのです。このような「関係の形式化」の必要性は、上記のような複雑なサンプルでは、より明確になるであろう。例えば、クラスのメンバ自体が何かへのポインタである場合。

POINTER_AUTOMATICとPOINTER_DYNAMICを 扱う統一された方法を提供することによって、これらのタイプのポインタが類似しているという誤解を与えて います。しかし、実際にはこれらは異なるエンティティであり、異なる処理を必要と します。これがこのブランチの主な主題 です。最も明白なものはもちろん、POINTER_AUTOMATICが常に実際のオブジェクトを指す のに対し、POINTER_DYNAMICは空にもなり得るというものです

そして、データアクセスのすべての異なるバリエーションを思い出してください(C/C++とはいえ、パスが一致する限り)。

オペレーターシンタックスリローダブルC言語で 実装
型Tのメンバークラス外での定義
配列の要素にアクセスするa[b] である。はいはいRT::operator[](Sb) です。
非対称性
間接参照*aはいはいRT::operator*()。R演算子*(Ta)。
リファレンス(「アドレスa」)。& aはいはいR オペレータT::operator&()。R演算子Ta
構造体のメンバを参照する(「aが指す オブジェクトのbメンバ」)。a->bはいはいR*T::operator->();[注5]
N/A
構造体のメンバへの参照( オブジェクトa b メンバ」)。a. bいいえはい非対称性
aが指す オブジェクトのbが指す メンバ[注6]。a->*bはいいいえR オペレータT::operator->*(Sb) です。Rオペレータ->*(Ta, Sb)
オブジェクトaのbが指す メンバーa.*bいいえいいえN/A
 
SemenTalonov:

POINTER_AUTOMATICが常に実オブジェクトを指して いる場合POINTER_DYNAMICも空 である可能性があるからです

もし「最も明白なこと」がすでに誤りであるなら、他のすべてを真剣に検討し、答える価値があるのだろうか。

POINTER_AUTOMATICは 変数のタイプではなく、そのステータスです。次の瞬間には、その状態はまったく変わっているかもしれません。もちろん、POINTER_INVALIDも含めて。
 
Ilya Malev:

最も明白なこと」がすでに誤りであるなら、それ以外のことを真剣に検討し、対応する価値があるのだろうか。

可能であれば、この点について明確にしてほしい

 
Ilya Malev:
POINTER_AUTOMATICは、変数の型ではなく、その状態です。次の瞬間には、その状態はまったく変わっているかも しれない

確かに、タイプではありません。例えばオートオブジェクトがPOINTER_DYNAMICという ステータスを持つポインタになるということですか? ここでいうPOINTER_INVALIDとは、例えばポインターを宣言した ときの状態を 指します。

 
SemenTalonov:

できれば、この点について明確にしてほしい。

ただ、MCLではC++と同じではないらしい。ここでは、ポインタは全く別のデータ型ではないので、両方ともオブジェクトであり、変数にはそのハンドルが格納されます。変数は(*なしで宣言された場合)隠された定数プロパティを持ちますが、それは本質的に異なる型の変数を作るものではなく、異なるハンドルを割り当てることを禁止しているだけです。

 

つまり、宣言する

   A* const b=new A;

そして、まったく同じ「自動オブジェクト」ができ、ただそれを自分で削除することになります。