Fehler, Irrtümer, Fragen - Seite 1206

 
stringo:

Das ist richtig. Die exakte Übereinstimmung hat Vorrang. Und das ist auch richtig so.

Warum brauchen Sie eine solche Vereinheitlichung? Vereinheitlichung der Verarbeitung fehlerhaft gestalteter Programme

Eine Vereinheitlichung ist erforderlich, damit derselbe Code gleichermaßen mit C++ und MQL funktioniert. In C++ wird diese Reihenfolge aus einem bestimmten Grund (!) eingehalten (sonst gibt es irgendwann Unklarheiten). Ursprünglich dachte ich, dass der C++-Compiler unlogisch ist und/oder sogar einen Fehler hat, aber jetzt bin ich geneigt zu glauben, dass es objektive Gründe für einen solchen Ansatz gibt. Hier ist ein Beispiel in MQL, das zeigt, dass X:: g eine vollständige Übereinstimmung ist, aber Y::g trotzdem aufgerufen wird - wie in C++, was dem vorherigen Beispiel widerspricht https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

class A {};
class B : public A {};
class C : public B {};
class X {
public:
        virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
        virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public:
        virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart()
{
        C* c = new C;
        Y* y = new Y;
        Print( y.g( c, c ));
}

Ergebnis: 3

Es stellt sich heraus, dass C++ eine "unlogische" aber eindeutige Reihenfolge hat, während MQL eine zufällige Reihenfolge hat - wenn es eine exakte Übereinstimmung von Typen gibt, wird in einem Fall eine Basisklasse und im anderen Fall eine abgeleitete Klasse aufgerufen

 
A100:

Eine Vereinheitlichung ist erforderlich, damit derselbe Code gleichermaßen mit C++ und MQL funktioniert. In C++ wird diese Reihenfolge aus einem bestimmten Grund (!) eingehalten. Ursprünglich dachte ich, dass der C++-Compiler unlogisch ist und/oder sogar einen Fehler hat, aber jetzt bin ich geneigt zu glauben, dass es einen objektiven Grund für einen solchen Ansatz gibt. Hier ist ein Beispiel in MQL, das zeigt, dass X:: g eine vollständige Übereinstimmung ist, aber Y::g trotzdem aufgerufen wird - wie in C++, was dem vorherigen Beispiel widerspricht

Ergebnis: 3

Es stellt sich heraus, dass C++ eine "unlogische", aber eindeutige Reihenfolge hat, während MQL eine zufällige Reihenfolge hat - wenn die Typen genau übereinstimmen, wird in einem Fall die Basisklasse und in einem anderen Fall eine abgeleitete Klasse aufgerufen.

Von welcher C++-Implementierung sprechen Sie genau? Wie gut entspricht diese Implementierung dem C++-Standard? Was besagt der C++-Standard über die Auswahl überladener Funktionen?

Eigentlich ist die von Ihnen beschriebene Funktionsüberladung eine Folge des falschen Designs.

Die Portierung von Quellcode ist ein Mythos. Nur das Testprogramm funktioniert in verschiedenen C++-Umgebungen auf die gleiche Weise. Das reale Programm (wir sprechen hier von Tausenden von Codezeilen mit einem realen Anwendungswert) wird zumindest in einigen Aspekten in verschiedenen Umgebungen unterschiedlich funktionieren. Und von einer Vereinheitlichung von MQL mit C++ kann überhaupt keine Rede sein - das ist eine Verschwendung des Genpools...

 
A100:

Eine Vereinheitlichung ist erforderlich, damit derselbe Code gleichermaßen mit C++ und MQL funktioniert. In C++ wird diese Reihenfolge aus einem bestimmten Grund (!) eingehalten (sonst gibt es irgendwann Unklarheiten). Ursprünglich dachte ich, dass der C++-Compiler unlogisch ist und/oder sogar einen Fehler hat, aber jetzt bin ich geneigt zu glauben, dass es objektive Gründe für einen solchen Ansatz gibt. Hier ist ein Beispiel in MQL, das zeigt, dass X:: g eine vollständige Übereinstimmung ist, aber Y::g trotzdem aufgerufen wird - wie in C++, was dem vorherigen Beispiel widerspricht https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

Ergebnis: 3

Es stellt sich heraus, dass C++ eine "unlogische", aber eindeutige Reihenfolge hat und MQL eine zufällige Reihenfolge hat - bei exakter Typübereinstimmung wird in einem Fall eine Basisklasse und in einem anderen Fall eine abgeleitete Klasse aufgerufen

Sie scheinen sich in diesem Beispiel zu irren, denn wenn die Klasse Y von X und nicht von C geerbt wird, wäre das Verhalten dasselbe wie im vorherigen Beispiel.
 
stringo:

Was besagt der C++-Standard über die Reihenfolge der Auswahl überladener Funktionen?

Um Strawstrup zu zitieren: "C++ verlangt eine exakte Typübereinstimmung zwischen einer virtuellen Funktion in einer Basisklasse und einer Ersatzfunktion in einer abgeleiteten Klasse".

Ich habe mir das Problem nun angesehen und bin zu dem Schluss gekommen, dass C++ korrekt ist. In beiden obigen Beispielen verdeckt g() der abgeleiteten Klasse g() der Basisklasse (und ersetzt es nicht). Und der Virtualitätsmechanismus wird nur aktiviert, wenn eine Substitution stattfindet, und die Substitution erfordert eine exakte Typübereinstimmung (außer beim Rückgabetyp). Nur die Genauigkeit der Rückgabeart kann von der jeweiligen Implementierung abhängen.

 
mql5:
Sie scheinen sich in diesem Beispiel zu irren. Wenn die Klasse Y von X und nicht von C geerbt würde, wäre das Verhalten das gleiche wie im vorherigen Beispiel.

Ja, ich habe mich hier geirrt, und es stellt sich heraus, dass sowohl C++ als auch MQL eindeutige, aber unterschiedliche Reihenfolgen von Substitution und Verschleierung haben. Bitte beachten Sie meine Argumente im vorigen Beitrag über den Unterschied zwischen Substitution und Verschleierung

Die Tatsache, dass C++ beim Verstecken eine Warnung ausgibt, zeigt, dass diese Reihenfolge absichtlich gewählt wurde.

class A {};
class B : public A {};

class X {
public:
        virtual int g( A* a )
        virtual int f( B* a )
};
class Y : public X {
public:
        virtual int g( A* a ) //подмена  X::g
        virtual int f( A* a ) //сокрытие X::f
};
 
A100:

Ja, ich habe mich hier geirrt, und es stellt sich heraus, dass sowohl C++ als auch MQL eindeutige, aber unterschiedliche Reihenfolgen von Substitution und Verschleierung haben. Bitte beachten Sie meine Argumente im vorigen Beitrag über den Unterschied zwischen Substitution und Verschleierung

Die Tatsache, dass C++ beim Ausblenden eine Warnung erzeugt, deutet darauf hin, dass diese Reihenfolge absichtlich gewählt wurde

Der MQL-Compiler betrachtet bei der Suche nach einer Methode (Funktion) die Übergabe an einen Elternteil nicht als Casting, wie es bei C++ von MS zum Beispiel der Fall zu sein scheint.

Vielen Dank für den Beitrag, wir werden darüber diskutieren (nachdenken).

 
mql5:
Der MQL-Compiler betrachtet bei der Suche nach einer Methode (Funktion) die Übergabe an ein übergeordnetes Element nicht als Casting, wie es z. B. bei MS C++ der Fall zu sein scheint.

Danke für die Nachricht, wir werden darüber nachdenken.

Beachten Sie, dass nicht nur von MS - Ich habe Borland C++ 5.5.1

Stroustrup schreibt, dass es sonst unangenehme Folgen haben kann, wenn man "über das Ende des Klassenobjekts hinausgeht".

 
A100:

Um Strawstrup zu zitieren: "C++ verlangt eine exakte Typübereinstimmung zwischen einer virtuellen Funktion in einer Basisklasse und einer Ersatzfunktion in einer abgeleiteten Klasse".

Ich habe mir das Problem nun angesehen und bin zu dem Schluss gekommen, dass C++ korrekt ist. In beiden obigen Beispielen verdeckt g() der abgeleiteten Klasse g() der Basisklasse (und ersetzt es nicht). Und der Virtualitätsmechanismus wird nur aktiviert, wenn eine Substitution stattfindet, und die Substitution erfordert eine exakte Typübereinstimmung (außer beim Rückgabetyp). Nur die Genauigkeit der Rückgabeart kann von der jeweiligen Implementierung abhängen.

Moment mal, Moment mal. Es geht um das Überladen von Funktionen mit verschiedenen Parametern.

Virtuelle Funktionen hingegen haben immer Parameter desselben Typs. Virtuelle Funktionen sind nicht Gegenstand dieser Diskussion.

 
A100:

Beachten Sie, dass nicht nur von MS - ich verwendet Borland C++ 5.5.1

Stroustrup schreibt, dass es sonst unangenehme Folgen haben kann, wenn man "über das Ende des Klassenobjekts hinausgeht".

Wir haben das besprochen; wir werden das Verhalten des MQL-Compilers nicht ändern - es ist ein "zweischneidiges Schwert". Lassen Sie mich das erklären.

Das Problem ist nur relevant, wenn Änderungen an den vorgefertigten Klassen (in einem Arbeitsprogramm) vorgenommen werden.
Nachdem der Elternteil eine geeignetere Funktion hat, wird das Programm plötzlich aufhören zu funktionieren, weil statt der Methode des Nachkommens die Methode des Elternteils aufgerufen wurde.
Nun, wenn wir das MQL-Verhalten ändern, dann kann eine ähnliche Situation auftreten - beim Hinzufügen einer neuen Methode zum Nachkommen, anstelle der übergeordneten Funktion (ohne Parameter-Casting) die Nachkommen-Methode aufgerufen wird, und mit Parameter-Casting, und das Programm nicht mehr funktioniert wieder.

Somit werden keine anderen Probleme als die Kompatibilität mit C++ gelöst, außerdem wird die Änderung des Compilerverhaltens bestehende MQL-Programme beeinflussen.
 

Так как переменные типа структур и простых типов не имеют указателей, то применять к ним функцию GetPointer() запрещено.

Es ist auch verboten, einen Zeigerals Argument an eine Funktion zuübergeben(welche ???GetPointer oder irgendeine ?).In all diesen Fällen wird der Compiler einen Fehler melden.

Zitat aus der Dokumentation.

class A{
public:
   void operator= (const A* from){
      if (GetPointer(this) == GetPointer(from))      // а тут я передаю и все ок
         Alert(1);                                  // резутат 1  из за того что передаю this
      else
         Alert(2);
   }
};

class B : public A{
public:
   void operator= (const B& from){  
      if (GetPointer(this) == GetPointer(from))
         return;
      operator=((A*)(GetPointer(this)));
   }
};
  B b;
   B bb;                        // забыл написать создание объектов и вызов функции.
   b = bb;

Ich habe bereits verstanden, warum es nicht für Warnungen schimpft - es ist meine Schuld, dass ich einen falschen Zeiger in eine Funktion übergeben habe.