メソッド宣言の後の const 修飾子の意味 - ページ 6

 
定数メソッド
コンスタントメソッドは、そのクラスフィールドの値を変更しないという事実によって区別されます。CONSTFUという例を見てみましょう。
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

通常の nonFunc() メソッドでは alpha フィールドの値を変更できますが、定数メソッド conFunc() ではできません。alphaフィールドを変更しようとした場合、コンパイラはエラーを 報告します。
関数を定数にするには、関数プロトタイプの後、関数本体の前に const キーワードを指定する必要があります。関数宣言と定義が分離している場合、const修飾子は関数宣言と定義の両方で2回指定する必要があります。クラスフィールドからデータを読み取るだけのこれらのメソッドは、クラスオブジェクトのフィールドの値を変更する必要がないため、定数にすることは理にかなっています。

定数関数の使用は、コンパイラがエラーを検出するのに役立ち、また、リストの読者にその関数がオブジェクトフィールドの値を変更しないことを伝えることができます。定数関数は、後で見るように、定数オブジェクトを作成したり使用したりするために使用することができます。

Distanceクラスの例

一つのプログラムに多くの工夫を盛り込まないために、これまでの例では定数法を用いていない。 しかし、定数法を使うと便利な場面は結構あります。例えば、今回の例で繰り返し登場するDistanceクラスのshowdist()メソッドは、呼び出されたオブジェクトのフィールドを変更しない(してはいけない!)ので、定数化されているはずです。あくまでも、フィールドの現在値を画面に表示 することを目的としています。

...

Lafauré R. - C++によるオブジェクト指向プログラミング(第4版)2004年 P.250より引用

 
Dmitry Fedoseev:

この文脈では、型は語られないので、こういうことです。"自クラス "は明らかにそれ自身のインスタンス(=オブジェクト)です。

x メンバは bar メソッドと同じ クラスに属しています。

C obj._x - ここでは、_x メンバは外部クラス obj にあります。

なぜなら、_xは私たちが書いた私たちのクラスに属し、obj.xは私たちが扱う外国のクラスに属することは明らかだからです。

OOP用語といえば、ここでの用語は全体的にちょっと(いや、かなり)あれな感じです。

ドミトリー、そんなこと言ったら、これから初めてOOPに触れる人がおかしくなっちゃうよ。

この文脈では型の話をしてないからそういうことなんでしょう。"Its class "は明らかにそれ自身のインスタンス(=オブジェクト)です。

当たり前といえば当たり前なんでしょうけど。読んでいて思ったのですが、クラスが命令、抽象化である場合、メンバー_xはどうやってクラスに所属することができるのでしょうか、ご自身がおっしゃるように。

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

メソッド宣言の後のconst修飾子は何を意味するのですか?

ドミトリー・フェドセーエフ, 2016.02.01 19:06

オブジェクトはどのようにしてメソッドを呼び出すのですか?メソッドは、関数から呼び出すことも、他のメソッドから呼び出すこともできます。

呼び出されるのは、単なるクラスメソッドではなく、特定のオブジェクトのメソッドです。クラス自体は抽象化されたものです。

C obj._x - ここでは、メンバー _x が余計なクラス obj.C に入っています。

クラスとクラスのインスタンスの違いがわからないってマジか!?そんなことを言ったら、読者の脳が爆発して、(引用した例では)一つのクラスのインスタンスなのに、メソッドを呼び出したオブジェクトとobjオブジェクトは別のクラスのインスタンスだと勘違いしてしまいますから、絶対にダメです。

OOPの用語といえば、ここでの用語はすべてそれなり(あるいはそれ以上)です。

専門用語は、理解できないと「ちょっとアレ」なのです。クラス(命令)とは何か、クラスのオブジェクト(インスタンス)とは何かを明確に理解すればいいのです。そうすれば、多くの問題はひとりでに消えていくでしょう。もちろん、あなたの考えを変えることはできないので、このテーマで議論を続ける意味はないと思います。残念なことです。
 
unreal:
定数メソッド
コンスタントメソッドは、そのクラスフィールドの値を変更しないという事実によって区別されます。CONSTFUという例を見てみましょう。
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

通常の nonFunc() メソッドでは alpha フィールドの値を変更できますが、定数メソッド conFunc() ではできません。alphaフィールドを変更しようとした場合、コンパイラはエラーを 報告します。
関数を定数にするには、関数プロトタイプの後、関数本体の前に const キーワードを指定する必要があります。関数宣言と定義が分離している場合、const修飾子は関数宣言と定義の両方で2回指定する必要があります。クラスフィールドからデータを読み取るだけのこれらのメソッドは、クラスオブジェクトのフィールドの値を変更する必要がないため、定数にすることは理にかなっています。

定数関数の使用は、コンパイラがエラーを検出するのに役立ち、また、リストの読者にその関数がオブジェクトフィールドの値を変更しないことを伝えることができます。定数関数は、後で見るように、定数オブジェクトを作成したり使用したりするために使用することができます。

Distanceクラスの例

一つのプログラムに多くの工夫を盛り込まないために、これまでの例では定数法を用いていない。 しかし、定数法を使うと便利な場面は結構あります。例えば、今回の例で繰り返し登場するDistanceクラスのshowdist()メソッドは、呼び出されたオブジェクトのフィールドを変更しない(してはいけない!)ので、定数化されているはずです。あくまでも、フィールドの現在値を画面に表示 することを目的としています。

...

Lafauré R. - C++によるオブジェクト指向プログラミング(第4版)2004年 P.250より引用

しかし、OOPの本でも正しいとか間違っているとか書かれていたら、どんな順番になるのでしょうか。とはいえ、もしかしたら翻訳のせいかもしれませんが。
 
Alexey Kozitsyn:

ドミトリー、こんな話をしたら、初めてこんな用語を使ってOOPに親しみ始めた人たちがおかしくなってしまうこと、わかっているんですか?

当たり前といえば当たり前なんでしょうけど。クラスが命令、抽象化であるなら、メンバー_xがクラスに属することができるのか、ご自身でおっしゃったように、読みながら考えています。

クラスとクラスのインスタンスの違いを本気で理解してないのか!?そんなことを言うと、読者の脳が爆発して、メソッドを呼び出したオブジェクトとobjオブジェクトは、(あなたの挙げた例では)同じクラスのインスタンスであるにもかかわらず、異なるクラスのインスタンスであると考えるようになるから、絶対にダメだ。

専門用語というのは、その後、自分が何を扱っているのかが分からないと「ちょっとあれ?クラス(命令)とは何か、クラスのオブジェクト(インスタンス)とは何かを明確に理解すればいいのです。そうすれば、多くの問題はひとりでに消えていくでしょう。もちろん、あなたの考えを変えることはできないので、このテーマで議論を続ける意味はないと思います。残念なことです。

なぜ、私の考えを変えなければならないのですか?何について考えを変えたの?何もかもが順調です。このスレッドの最初の投稿で、完全に矛盾なく理解することができました。

また、参考文献で十分理解できると書いたのはあなたであることに注意してください。では、何を論じているのか全く不明なのですが?

ps.自分の妄想を勝手に決めつけないでください。

 
George Merts:

個人的には、constメソッドは、クラス変数を変更できないメソッドと理解していました。

というのも、ベースとなるメソッドは不変なのに、メソッドの再定義で何かを変更しなければならない状況によく遭遇 するからです(ここですでに言及されています)。

静的な手法が多用されている。ほとんどすべての複雑なクラスで。通常、これらはクラス変数にアクセスする必要のない「奉仕的」な追加メソッドです。

また、「1日の秒数」のような定数は、#defineではなく、静的なconstを使うようにしています。この場合、このような定数の宣言と初期化は別の場所にあるのですが、型制御が発生するので、何度も助けられました。

私がほとんど使っていないものと同じです。実は、このフォーラムの参加者の一人が、プライベートメッセージで「なぜ必要なのか」と聞いてきたので、このトピックを立ち上げたのです。
 
George Merts:

個人的には、constメソッドは、クラス変数を変更できないメソッドと理解していました。

というのも、メソッドのオーバーライドで何かを変更する必要があり、ベースメソッドは一定であるという状況に何度も出くわしたからです(すでにここで言及されていますね)

あなたはそのために使ってはいけないし、私はそのために使っているのです。

zaskok3 です。

私にとっては、constとstaticを使うことで、自分のコードの可読性と理解度が大きく向上します。また、自作アーキテクチャのバグや不具合を実装の早い段階で発見できることも多い のです。


私はすべて自分のためだけに書いています。どうせ変えてはいけないデータも変えないことになりそうですし。しかし、自分の愚かさから自分を守りたいという思いから、私はOOPアーキテクチャを、アクセスしなければならないものだけを変更できるような形で固定しているのです。あとは、そうではない。そしてここで、const+継承型が大きな助けとなる。おすすめです。
 

私はプログラミングが苦手なので、EAのコンパイルを手伝ってくれる親切な方、とてもお願いします。

これは、'delete' をコンパイルするときに表示されるエラーです - name expected.

コード内のエラーは赤でハイライトされています

void delete(int type){。

if(OrdersTotal()>0){。

for(i=OrdersTotal()-1;i>=0;i--){。

OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

if(type!=6 && type!=7 && type!=8)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==type)OrderDelete(OrderTicket().OrderTicket();

if(type==6)if(OrderSymbol()==Symbol()&&OrderMagicNumber()==magic&&)です。OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP || OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT)OrderDelete(OrderTicket());

if(type==7)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)OrderDelete(OrderTicket()).OrderTicket()).OrderDelete(OrderTicket());

if(type==8)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLIMIT)OrderDelete(OrderTicket()).OrderTicket());

}

}

}


以下は別のエラーです '(' - オブジェクトポインタが期待されます。

if(oppositedelete){delete(OP_SELLSTOP);delete(OP_SELLLIMIT);}となります。

そして、ここで'}'- すべてのコントロールパスが値を返すわけではない

int countglobal(){。

int cnt=0;

if(OrdersTotal()>0){。

for(i=OrdersTotal()-1;i>=0;i--){。

OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

cnt++です。

}

return(cnt);

}

}

 
zaskok3:

あなたはそのために使ってはいけないし、私はそのために使っているのです。

長く書かれた関数を読んで理解する際に、const指定が有効であることには同意します。しかし、変数へのアクセスを制限 するには、private-protected-publicの異なるセクションで宣言する方が理にかなっているように思います(個人的には、変数をpublicと宣言することはなく、メソッドのみです)。

内部クラス変数が子孫で変更されてはいけないという状況は、私には考えにくいです。

 
Anton Razmyslov:

EAのコンパイルで親切な方お願いします、プログラミングは苦手です。

ロジックでは?なぜこのような質問でプロフィールのないトピックを乱立させるのでしょうか?
 

ところで、Const修飾子は、自分のクラス内のデータを変更できないだけでなく、定数でないメソッドに対応することさえできないということは、誰も書いていない。簡単な例:ポジションクラスがあり、ポジションのリストを利益でソートする必要があります。利益については、リクエストにより算出されます。

class CPosition : public CObject
{
private:
   double m_profit;
   void CalculateProfit()
   {
      m_profit = 31337;
   }
public:
   CPosition(void) : m_profit(0.0)
   {
   }
   double Profit(void)const
   {
      if(m_profit == 0.0)
         CalculateProfit(); // <- Константный метод вызывает блок рассчета и вызывает ошибку
      return m_profit;
   }
   virtual int Compare(const CObject *node,const int mode=0) const
   {
      const CPosition* pos = node;
      if(pos.Profit() > Profit())
         return 1;
      else if(pos.Profit() < Profit())
         return -1;
      return 0;
   }
};

このコードでは、Profitメソッドは定数ですが、Profitがまだ計算されていない場合は、定数でないCalcultaeProfitメソッドを参照するため、エラーが発生します。

なお,Profitメソッド自体は絶対的に安全であり,返す値が空でないことを保証している.しかし、定数法では、舞台裏の計算や高度なコードセキュリティを放棄して、何がなぜ制限されるのかわからないような、いきなりの構造を採用しなければならない。