PLOです。アプリケーションの問題 - ページ 13

 
TheXpert:
混乱しないように例を示してください、そうすれば私は答えます。

//1-ый вариант. Переменная-член strA инициализируется автоматически
class A
  {
public:
   string            strA;
                     A(void) { Print("strA=",strA); };
                    ~A(void){};
  };
//2-ой вариант. Переменная-член strB инициализируется при помощи инициализатора пользовательским значением
class B
  {
public:
   string            strB;
                     B(const string str) : strB(str) { Print("strB=",strB); }
                    ~B(void){};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   A a1;
   B b1("Пользовательское значение");
  }

例を挙げると簡単です。仮にa1.strAメンバの自動初期化に15サイクルの「コンピュータサイクル」が費やされたとすると、b1.strBメンバの初期化にも15サイクルが費やされているという予備的な結論に至ったわけである。これでいいのでしょうか?

 

標準ライブラリの CExpert クラスでは、次のようなガード宣言があります。

//--- trading objects
CExpertTrade     *m_trade;    // trading object
CExpertSignal    *m_signal;   // trading signals object
CExpertMoney     *m_money;    // money manager object
CExpertTrailing  *m_trailing; // trailing stops object

同時に、このオブジェクトのコンストラクタには、以下の文字列が含まれています。

m_trade    =NULL;
m_signal   =NULL;
m_money    =NULL;
m_trailing =NULL;

私のクラスで似たようなものを作ろうとしましたが、それ以上の初期化(InitやInitXXXなど)はしていません。

コンパイラは警告やエラーもなくすべてコンパイルしてくれたのですが、チャートにEAをインストールしようとすると、クリティカルエラー281 (Invalid pointer access)が出て、チャートからEAが削除されてしまいました。

この点に関して、いくつか質問があります。

1.コンストラクタでどのように指定すればよいですか(NULLを指定するか、特定のオブジェクトへのポインタを指定するか)?

2.InitTrade 型ポインタの初期化は必須ですか?

 
Interesting:

標準ライブラリの CExpert クラスでは、次のようなガード宣言があります。

同時に、このオブジェクトのコンストラクタには、以下の文字列が含まれています。

私のクラスで似たようなものを作ろうとしましたが、それ以上の初期化(InitやInitXXXなど)はしていません。

コンパイラは警告やエラーもなくすべてコンパイルしてくれたのですが、チャートにEAをインストールしようとすると、クリティカルエラー281 (Invalid pointer access)が出て、チャートからEAが削除されてしまいました。

この点に関して、いくつか質問があります。

1.コンストラクタでどのように指定すればよいですか(NULLを指定するか、特定のオブジェクトへのポインタを指定するか)?

2.InitTrade 型ポインタの初期化は必須ですか?

1.どちらも正解です。全てはクラスの特定の実装に依存します(特にCExpertでは ありません)。しかし、boolを 返すInitXXX メソッドでダイナミックオブジェクトを作成した方が良い(コンストラクタが実行結果を返さないため、初期化フラグをリセットしてから解析(フラグ)する必要があるため)。

2.もちろん、そうです。そうでない場合は、クリティカルエラー281 (Invalid pointer access)が発生します。

PS.ところで、ありがとうございます。使用前にポインタチェックを入れる必要があるね。

 
Yedelkin:

例を挙げると簡単です。仮にa1.strAメンバの自動初期化に15サイクルの「コンピュータサイクル」が費やされたとすると、b1.strBメンバの初期化にも15サイクルが費やされているという予備的な結論に至ったわけである。これでよいのでしょうか?

いや、まったくタクトがない。あるいは、時計はあまり関係ないのかもしれません。
 
TheXpert:
いや、時計は全然関係ないんですよ。まあ、あるいは時計についてはあまり関係ないのですが。

では、非常に簡単な質問ですが、上記の例のメンバー a1.strA とメンバー b1.strB のどちらが時間的に早く初期化できるでしょうか?

あるいは、「一点一画」をどう読むか?プログラミングを「マシン・プロセッサ」レベルで学ぶことは、物理的に不可能なのです。

 
Yedelkin:

では、非常に単純な質問ですが、上記の例のメンバー a1.strA とメンバー b1.strB のどちらが時間的に早く初期化できるでしょうか?

あるいは、「一点一画」をどう読むか?マシンプロセッサー」レベルのプログラミングを学ぶ方法は、物理的に存在しないのです。

a1.strAの初期化処理は、単にその場でゼロになるため、より高速に初期化されます。b1.strBについては、メモリ確保が行われます。

しかし、この差は、初期化周りのコードを考慮しても1%よりずっと小さいので、測定するのはかなり困難です

 
Yedelkin:

より高速に初期化する

は不正解です。
 
stringo:

b1.strBについては、メモリ確保が行われます。

私のロジックのミッシングリンクです。

TheXpert さん、ありがとうございます。ポイントを自分の言葉で説明しようとした。本当に正しい問いは、知る人ぞ知るというのは、私も同感です。でも、普通は私のようなレベルの高い質問はしてきませんよ :)

 
uncleVic:

1.どちらの意味でも正しいです。全てはクラスの具体的な実装に依存します(特にCExpertでは ありません)。しかし、boolを 返すInitXXX メソッドで動的オブジェクトを作成した方が良い(コンストラクタが実行結果を返さないため、初期化フラグのリセット/アンセットを行ってから、そのフラグを解析する必要があるため)。

2.もちろん、そうです。そうでない場合は、クリティカルエラー281 (無効なポインタアクセス)です。

PS.ところで、ありがとうございます。使用前にポインタチェックを入れる必要があるね。

ありがとうございます。これですべてのものが定位置に収まりました。しかし、もう一つ疑問があります。 エラー281が発生したが、Expert Advisorがアンロードされない方が良いとします。どうしたらいいのでしょうか?

私の質問を明確にさせてください - 281エラーが初期化のすべてのステップの後に発生したが、それは全くそれを実行しないように致命的にExpert Advisorの主な作業に影響を与えません場合はどうすればよいですか?

 
Interesting:

エラー281が発生したが、EAがアンロードされないことが望ましいとする。では、どうすればいいのでしょうか。

私の質問を明確にさせてください:すべての初期化ステップの後にエラー281が発生したが、それはエキスパートアドバイザーの主要な作業に影響を与えず、それをまったく実行しないほど致命的ではない場合、どうすればよいのでしょうか?

"無効なポインタへのアクセス" =="無効なポインタへのアクセスを試みている"?はい」の場合

無効なポインタにアクセスしようと すると、 プログラムがクラッシュ する。そのため、ポインターを使用する前にCheckPointer() 関数を使用する必要性があります。次のような場合、ポインタは無効となることがあります。

  • ポインタがNULLの
  • 場合、オブジェクトがdelete
  • 演算子によって破壊された場合。