Was der Modifikator const nach einer Methodendeklaration bedeutet - Seite 6

 
Konstante Methoden
Konstante Methoden zeichnen sich dadurch aus, dass sie die Werte ihrer Klassenfelder nicht verändern. Schauen wir uns ein Beispiel namens CONSTFU an:
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

Eine normale nonFunc()-Methode kann den Wert des Alpha-Feldes ändern, eine konstante Methode conFunc() jedoch nicht. Wenn versucht wird, das Alpha-Feld zu ändern, meldet der Compiler einen Fehler.
Um eine Funktion zu einer Konstanten zu machen, muss das Schlüsselwort const nach dem Funktionsprototyp, aber vor dem Beginn des Funktionskörpers angegeben werden. Wenn Funktionsdeklaration und -definition getrennt sind, muss der const-Modifikator zweimal angegeben werden - sowohl in der Funktionsdeklaration als auch in der Definition. Es ist sinnvoll, diese Methoden, die nur Daten aus dem Klassenfeld lesen, konstant zu machen, da sie die Werte der Klassenobjektfelder nicht ändern müssen.

Die Verwendung von konstanten Funktionen hilft dem Compiler, Fehler zu erkennen, und teilt dem Leser des Listings mit, dass die Funktion die Werte der Objektfelder nicht verändert. Konstante Funktionen können zum Erstellen und Verwenden von konstanten Objekten verwendet werden, wie wir später sehen werden.

Ein Beispiel für die Klasse Distance

Um nicht zu viele Neuerungen in ein einziges Programm aufzunehmen, haben wir in unseren Beispielen bisher keine konstanten Methoden verwendet. Es gibt jedoch eine ganze Reihe von Situationen, in denen die Verwendung konstanter Methoden sinnvoll ist. Die Methode showdist() der Klasse Distance, die in unseren Beispielen immer wieder auftaucht, hätte beispielsweise konstant gemacht werden sollen, da sie die Felder des Objekts, für das sie aufgerufen wird, nicht verändert (und auch nicht verändern sollte!). Es ist nur dazu gedacht, die aktuellen Werte der Felder auf dem Bildschirm anzuzeigen.

...

entnommen aus S. 250, Lafauré R. - Object-Oriented Programming in C++ (4. Aufl.) 2004

 
Dmitry Fedoseev:

Das ist gemeint, denn in diesem Zusammenhang ist nicht von Typus die Rede. "Eigene Klasse" ist offensichtlich eine eigene Instanz (d. h. ein Objekt).

Das Element_x gehört zur selben Klasse wie die Methode bar.

C obj._x - hier ist das _x-Mitglied in einer fremden Klasse obj.

Es scheint mir akzeptabel, eher von einer Klasse als von einer Instanz zu sprechen, denn es ist offensichtlich, dass _x zu unserer Klasse gehört, die wir schreiben, und obj.x zu der fremden Klasse, die wir behandeln.

Apropos OOP-Terminologie, die ganze Terminologie hier ist ein bisschen davon (oder sogar viel).

Dmitry, du verstehst doch, dass diejenigen, die sich zum ersten Mal mit OOP und dieser Terminologie vertraut machen, durchdrehen, wenn du so redest!

Das ist es, was Sie meinen, denn wir sprechen in diesem Zusammenhang nicht von einem Typ. "Eigene Klasse" ist offensichtlich eine eigene Instanz (d. h. ein Objekt).

Wahrscheinlich ist es für Sie offensichtlich. Ich lese und frage mich, wie ein Mitglied _x zu einer Klasse gehören kann, wenn die Klasse eine Anweisung ist, eine Abstraktion, wie Sie selbst sagten:

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Was bedeutet der Modifikator const nach der Methodendeklaration?

Dmitry Fedoseev, 2016.02.01 19:06

Wie kann ein Objekt eine Methode aufrufen? Eine Methode kann von einer Funktion oder von einer anderen Methode aus aufgerufen werden.

Es ist nicht nur eine Klassenmethode, die aufgerufen wird, sondern eine Methode eines bestimmten Objekts. Die Klasse selbst ist eine Abstraktion.

C obj._x - hier ist das Mitglied _x in einer fremden Klasse obj.

Verstehen Sie wirklich nicht den Unterschied zwischen einer Klasse und einer Instanz einer Klasse? Das darf man auf keinen Fall sagen, denn dann explodiert das Gehirn des Lesers, und er wird denken, dass das Objekt, das die Methode aufgerufen hat, und das Objekt obj Instanzen verschiedener Klassen sind, obwohl sie Instanzen einer Klasse sind (in dem von Ihnen zitierten Beispiel).

Apropos OOP-Terminologie, die gesamte Terminologie hier ist ein bisschen davon (oder sogar sehr viel).

Terminologie ist eine "Kleinigkeit", wenn man nicht versteht, womit man es zu tun hat. Sie müssen nur klar verstehen, was eine Klasse (Anweisung) ist und was ein Objekt (Instanz) einer Klasse ist. Und dann werden viele Probleme von selbst verschwinden. Offensichtlich werde ich Sie nicht umstimmen können, daher sehe ich keinen Sinn darin, die Diskussion über dieses Thema fortzusetzen. Das ist sehr bedauerlich.
 
unreal:
Konstante Methoden
Konstante Methoden zeichnen sich dadurch aus, dass sie die Werte ihrer Klassenfelder nicht verändern. Schauen wir uns ein Beispiel namens CONSTFU an:
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

Eine normale nonFunc()-Methode kann den Wert des Alpha-Feldes ändern, eine konstante Methode conFunc() jedoch nicht. Wenn versucht wird, das Alpha-Feld zu ändern, meldet der Compiler einen Fehler.
Um eine Funktion zu einer Konstanten zu machen, muss das Schlüsselwort const nach dem Funktionsprototyp, aber vor dem Beginn des Funktionskörpers angegeben werden. Wenn Funktionsdeklaration und -definition getrennt sind, muss der const-Modifikator zweimal angegeben werden - sowohl in der Funktionsdeklaration als auch in der Definition. Es ist sinnvoll, diese Methoden, die nur Daten aus dem Klassenfeld lesen, konstant zu machen, da sie die Werte der Klassenobjektfelder nicht ändern müssen.

Die Verwendung von konstanten Funktionen hilft dem Compiler, Fehler zu erkennen, und teilt dem Leser des Listings mit, dass die Funktion die Werte der Objektfelder nicht verändert. Konstante Funktionen können zum Erstellen und Verwenden von konstanten Objekten verwendet werden, wie wir später sehen werden.

Ein Beispiel für die Klasse Distance

Um nicht zu viele Neuerungen in ein einziges Programm aufzunehmen, haben wir in unseren Beispielen bisher keine konstanten Methoden verwendet. Es gibt jedoch eine ganze Reihe von Situationen, in denen die Verwendung konstanter Methoden sinnvoll ist. Die Methode showdist() der Klasse Distance, die in unseren Beispielen immer wieder auftaucht, hätte beispielsweise konstant gemacht werden sollen, da sie die Felder des Objekts, für das sie aufgerufen wird, nicht verändert (und auch nicht verändern sollte!). Es ist nur dazu gedacht, die aktuellen Werte der Felder auf dem Bildschirm anzuzeigen.

...

entnommen aus S. 250, Lafauré R. - Object-Oriented Programming in C++ (4. Aufl.) 2004

Aber welche Ordnung wird in Ihrem Kopf sein, wenn sogar in einem Buch über OOP entweder richtig oder falsch geschrieben wird. Vielleicht liegt es aber auch an der Übersetzung.
 
Alexey Kozitsyn:

Dmitry, ist Ihnen klar, dass diejenigen, die sich zum ersten Mal mit OOP und dieser Terminologie vertraut machen, verrückt werden, wenn Sie so reden?

Wahrscheinlich ist es für Sie offensichtlich. Ich lese und überlege, wie ein Mitglied _x zu einer Klasse gehören kann, wenn eine Klasse eine Anweisung, eine Abstraktion ist, wie Sie selbst sagten:

Du verstehst wirklich nicht den Unterschied zwischen einer Klasse und einer Instanz einer Klasse!? Das darf man auf keinen Fall sagen, weil es beim Leser eine Gehirnexplosion auslösen würde und er denken würde, dass das Objekt, das die Methode aufgerufen hat, und das Objekt obj Instanzen verschiedener Klassen sind, obwohl sie Instanzen derselben Klasse sind (in dem von Ihnen genannten Beispiel).

Terminologie ist dann "ein bisschen was davon", wenn man nicht versteht, womit man es zu tun hat. Sie müssen nur klar verstehen, was eine Klasse (Anweisung) ist und was ein Objekt (Instanz) einer Klasse ist. Und dann werden viele Probleme von selbst verschwinden. Offensichtlich werde ich Sie nicht umstimmen können, so dass ich keinen Sinn darin sehe, die Diskussion über dieses Thema fortzusetzen. Das ist sehr bedauerlich.

Warum sollten Sie meine Meinung ändern? Ihre Meinung über was ändern? Mit mir ist alles in Ordnung. Der erste Beitrag dieses Threads hat mir gereicht, um ein völlig konfliktfreies Verständnis zu haben.

Außerdem waren Sie es, der schrieb, dass der Verweis zum Verständnis ausreicht. Es ist also überhaupt nicht klar, worüber Sie sich streiten?

ps. Schieben Sie mir nicht einen Haufen Ihrer eigenen Wahnvorstellungen unter.

 
George Merts:

Ich persönlich habe const-Methoden immer als Methoden verstanden, die keine Klassenvariablen verändern können.

Ich habe sie sehr selten verwendet, weil ich oft auf eine Situation gestoßen bin, in der eine Neudefinition einer Methode eine Änderung erfordert, während die Basismethode konstant bleibt (dies wurde hier bereits erwähnt).

Statische Methoden werden in großem Umfang eingesetzt. In fast jeder komplexen Klasse. In der Regel handelt es sich um "dienende" zusätzliche Methoden, die keinen Zugriff auf die Klassenvariablen erfordern.

Außerdem versuche ich für Konstanten wie "Anzahl der Sekunden an einem Tag" eine statische Konstante zu verwenden, anstatt #define. In diesem Fall befinden sich Deklaration und Initialisierung einer solchen Konstante an verschiedenen Stellen, aber die Typkontrolle tritt auf und hilft mir mehr als einmal.

Das Gleiche benutze ich selten. Ich habe dieses Thema ins Leben gerufen, weil mich einer der Forumsteilnehmer in einer privaten Nachricht gefragt hat, warum ich sie brauche.
 
George Merts:

Ich persönlich habe const-Methoden immer als Methoden verstanden, die keine Klassenvariablen verändern können.

Ich habe sie sehr selten verwendet, weil ich immer wieder in die Situation komme, dass eine Methodenüberschreibung etwas ändern muss und die Basismethode konstant ist (ich habe es hier bereits erwähnt).

Sie benutzen sie NICHT aus diesem Grund, und ich benutze sie aus diesem Grund:

zaskok3:

Für mich erhöht die Verwendung von const und static die Lesbarkeit/Verständlichkeit meines eigenen Codes erheblich. So lassen sich Fehler oder Schwachstellen in der eigenen Architektur oft schon in einem frühen Stadium der Implementierung erkennen.


Ich schreibe alles nur für mich selbst. Und es sieht so aus, als würde ich einige Daten, die ich sowieso nicht ändern sollte, nicht ändern. Aber der Wunsch, mich vor meiner eigenen Dummheit zu schützen, lässt mich die OOP-Architektur so vernieten, dass sich nur das ändern lässt, was zugänglich sein muss. Der Rest ist es nicht. Und hier sind const + Vererbungstypen von großer Hilfe. Ich empfehle es.
 

Nette Leute helfen bitte beim Kompilieren von EA, ich bin nicht gut im Programmieren.

Diese Fehlermeldung erhalte ich beim Kompilieren von 'delete' - Name erwartet

Der Fehler im Code ist rot hervorgehoben

void delete(int type){

if(AufträgeSumme()>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();

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());

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

}

}

}


Hier ist ein weiterer Fehler '(' - Objektzeiger erwartet

if(oppositedelete){löschen(OP_SELLSTOP);löschen(OP_SELLLIMIT);}

Und hier '}' - nicht alle Kontrollpfade geben einen Wert zurück

int countglobal(){

int cnt=0;

if(AufträgeSumme()>0){

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

OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

cnt++;

}

zurück(cnt);

}

}

 
zaskok3:

Sie benutzen sie NICHT aus diesem Grund, und ich benutze sie aus diesem Grund:

Ich stimme zu, dass der const specifier nützlich ist, wenn man lange geschriebene Funktionen lesen und verstehen will. Aber den Zugriff auf Variablen einzuschränken, scheint mir sinnvoller zu sein, indem man sie in verschiedenen privat-geschützt-öffentlich-Abschnitten deklariert (ich persönlich deklariere Variablen nie als öffentlich, nur Methoden).

Es fällt mir schwer, mir eine Situation vorzustellen, in der eine interne Klassenvariable in Nachkommen nicht geändert werden sollte.

 
Anton Razmyslov:

Freundliche Menschen helfen mit EA-Kompilierung sehr bitte, nicht gut in der Programmierung.

Und in der Logik? Warum sollte man ein profilloses Thema mit Fragen wie dieser überfrachten?
 

Übrigens hat niemand geschrieben, dass der Const-Modifikator es nicht nur nicht erlaubt, Daten innerhalb der eigenen Klasse zu ändern, sondern sogar, nicht konstante Methoden anzusprechen. Ein einfaches Beispiel: Es gibt eine Positionsklasse, wir müssen die Liste der Positionen nach Gewinn sortieren. Der Gewinn wird durch den Antrag berechnet:

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;
   }
};

Dieser Code verursacht einen Fehler, da die Methode Profit zwar konstant ist, aber auf die nicht konstante Methode CalcultaeProfit verweist, wenn der Gewinn noch nicht berechnet wurde.

Beachten Sie, dass die Profit-Methode selbst absolut sicher ist: Sie garantiert, dass der Wert, den sie zurückgibt, nicht leer ist. Die konstante Methode erfordert jedoch den Verzicht auf Berechnungen hinter den Kulissen und eine hohe Codesicherheit zugunsten einiger sofort einsatzbereiter Konstruktionen, die nicht wissen, was und warum sie begrenzen.