Compilerfehler mit Template-Parameter = void* - Seite 6

 
Alexey Navoykov:

Alles funktioniert einwandfrei, warum denken Sie sich das aus?

Im Protokoll steht:

void A::~A()
void B::~B()

Warum bin ich überhaupt darauf reingefallen...

Nun, dann tut es mir leid, ich wusste nicht, dass man das tun kann, MKL ist ganz anders als C++. Positiv zu vermerken ist, dass das Entfernen von void* UB ist.

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Neue Version von MetaTrader 5 build 1930: Floating Chart Window und .Net Library in MQL5

Alexey Navoykov, 2018.12.15 02:44

Liebe Entwickler. Früher in einem der Threads haben wir den Compilerfehler diskutiert, der das implizite Casting einer Basisklasse in eine abgeleitete Klasse erlaubt, aber es scheint von Ihnen unbemerkt geblieben zu sein. Dies ist ein ernstes Problem, das die Fehlerprüfung erschwert und zu einem ständigen Kopfzerbrechen wird, wenn man aktiv OOP verwendet. Ein solches Casting sollte nur explizit sein. Dies ist eine allgemeine Regel sowohl für C++ als auch für C#.

class A {  };

class B : public A { };

A* a = new A;

B* b = a;  // Нет ошибки компиляции!

void f(B*) {  }

void OnInit()
{ 
  f(a);  // Нет ошибки компиляции!
}  

Und was ist hier zu tun?

class A {  };

class B : public A { };

A* a = new A;

void* v = a;

B* b = v;  // Нет ошибки компиляции!


Sollte dieses Verhalten auch als Fehler betrachtet werden?

 
Alexey Navoykov:

Wenn der Styler den Code schwer lesbar macht, warum sollte man ihn dann überhaupt verwenden?

Für mich ist ein Styler nur dann gut, wenn ALLE seine Regeln flexibel angepasst werden können.

Wenn Sie also den Code einer anderen Person in gedruckter Form lesen (oder in einem Forum, wie hier).

 
fxsaber:
Über Klammern
((A*)(b.GetPtr())).f(); // Доп. скобки, чтобы подчеркнуть, что именно имелось в виду, не полагаясь на приоритеты.

Nun, vielleicht hebt es Sie hervor, aber für mich ist es nur verwirrend. Aber wenn ich mir diesen Ausdruck ansehe, kann ich nicht sofort verstehen, wessen Methode hier aufgerufen wird. Aber in den beiden vorherigen Zeilen ist es sofort klar.

Um zu verstehen, was getan wird, sollten Sie alle Klammern öffnen. Je mehr Klammern es gibt, desto mehr Zeit wird damit verschwendet, herauszufinden, was vor sich geht, insbesondere wenn sie nicht durch Leerzeichen getrennt sind.

 
Alexey Navoykov:

Nun, vielleicht hebt es Sie hervor, aber für mich ist es nur verwirrend. Aber wenn ich mir diesen Ausdruck ansehe, kann ich nicht sofort verstehen, wessen Methode hier aufgerufen wird. Aber in den beiden vorherigen Zeilen ist alles auf einmal klar.

Um zu verstehen, was genau gemacht wird, müssen Sie alle Klammern aufklappen. Je mehr Klammern, desto mehr Zeit muss man aufwenden, um zu verstehen, was vor sich geht. Vor allem, wenn sie nicht durch Leerzeichen getrennt sind.

Zusätzliche Klammern sind nicht zum Lesen gedacht - überlassen Sie das dem Styler, der Leerzeichen setzt.

Aber für die Selbstbeherrschung beim Schreiben. Warum sollte ich mich auf die Prioritäten von jemandem verlassen, wenn ich in einem sensiblen Bereich schreibe, obwohl ich weiß, dass ich plattformübergreifenden Code schreibe (und nicht unbedingt nur MT4/5), der auf andere Sprachen portiert werden kann? Durch die zusätzlichen Klammern wird der Einfluss der sprachlichen Prioritäten vollständig eliminiert. Alles wird absolut eindeutig. Dadurch besteht eine 100-prozentige Sicherheit, dass an dieser Stelle nach dem nächsten Build nichts mehr schiefgehen kann.


Außerdem muss ich, wenn ich diese Klammerhölle lese, Zeit darauf verwenden, genau zu verstehen, was ich hier meine. Und zum Thema Sichtbarkeit.

bool a = (1 < 2) && (3 < 4);
bool b = 1 < 2 && 3 < 4;

Fragen wir uns, welche Option besser sichtbar ist?

 
fxsaber:

Zählt dieses Verhalten auch als Fehler?

Natürlich tut sie das. Das ist das Gleiche.

Es stellt sich also heraus, dass nichts erzeugt wird, wo ein Problem wirklich möglich ist und zumindest Warnungen erforderlich sind (oder sogar ein Kompilierungsfehler). Aber sie ersparen uns keine Warnungen, wenn uns Klammern aufgezwungen werden ) Und einige Leute hier schlagen sogar vor, die Kompilierung ohne Klammern zu verbieten und drohen uns mit Klatschbasen ) So leben wir...

 
Alexey Navoykov:

Ja, natürlich. Das ist das Gleiche.

Es stellt sich also heraus, dass, wenn es ein echtes Problem gibt und zumindest eine Warnung erforderlich ist (oder sogar ein Kompilierungsfehler), nichts angezeigt wird. Aber mit Klammern ersparen sie sich keine Warnungen ) Und einige Leute hier schlagen sogar vor, die Kompilierung ohne Klammern zu verbieten und drohen damit, Sie zu verprügeln ) So leben wir...

Sie brauchen also auch eine Warnung? Was ist das für eine Doppelmoral: an beiden Stellen ist das Verhalten eindeutig, aber bei Klammern sind Sie gegen Warnungen, und hier sind Sie dafür?

Sie brauchen eine Warnung, damit Sie keine schwer zu findenden Fehler machen. Die Schwierigkeit ist also eine subjektive Einschätzung. Bei Klammern macht man keine Fehler, aber hier schon. Und bei mir ist es umgekehrt.

An wen von uns sollten also die Regeln für die Erteilung von Verwarnungen angepasst werden?

 
Ilya Malev:

Ich wusste nichts von StringConcatenate, es ist schade, dass es in MT5 umgestaltet wurde und nicht ohne String s verwendet werden kann. Und das StringFormat ist viel schneller auf 4

Und im Allgemeinen aus irgendeinem Grund diese Operation der "Polling" einen Zeiger durch eine Zeichenfolge ist fast doppelt so langsam in 5, obwohl im Allgemeinen funktioniert es schneller gibt, manchmal um eine Reihenfolge

es ist möglich, dass StringConcatenate() 32 Bit ist, man weiß es nicht, die Entwickler haben bereits geschrieben, dass die Metaetiters in 5 und 4 gleich sind, vielleicht aus Kompatibilitätsgründen haben sie es "eingepackt"

Gestern habe ich versucht, Ihr Problem zu lösen. Das Problem ist, dass MQL nicht erlauben, Zeiger zu dereferenzieren. die Funktion in einer Klassenmethode kann über dynamic_cast<C_myclass >( func( ) ) aufgerufen werden, man kann einen Zeiger auf die Klasse über dynamic_cast< > erhalten, aber was macht man mit einem Zeiger? - man kann void *ptr neu zuweisen, aber das hat keinen Sinn, weil der Zeiger ohnehin nicht dereferenziert werden kann

 
pavlick_:

Wenn Sie CArayObject abschaffen wollen, müssen Sie einen Override (wie diesen https://www.mql5.com/ru/forum/170952/page110#comment_9894796) über die Basisklasse machen und sie in ein Array (möglicherweise Ihres) legen, aber dann brauchen Sie kein void* mehr.

Ich bin nicht gegen die Leere*, sie ist notwendig, aber in einer anderen Funktion.

Ich sehe den Sinn von Code by Reference nicht (obwohl ich auch keine Standardbibliotheken verwende). Wenn das Einfügen eines Objekts in ein Array die Erstellung einer Kopie des Objekts beinhaltet, muss die Zuweisungsmethode oder der Kopierkonstruktor explizit in dieser Klasse deklariert und beschrieben werden, da sonst keine Wrapper helfen. Wenn Sie nur einen Verweis auf ein Objekt in ein Array stellen müssen, brauchen Sie überhaupt keine Wrapper (warum?).

Übrigens scheinen Sie nicht zu wissen, dass if(p) delete p nicht mit "if reference points to an existing dynamic object, delete it" in mql identisch ist.

class A{};

void OnStart()
 {
  A *a=new A;
  if(a) Print("Кукареку!");
  if(CheckPointer(a)==POINTER_DYNAMIC) Print("Динамический объект существует и может быть удален");
  else                                 Print("Объект не существует, либо он автоматический");
  delete a;
  if(a) Print("Кукареку!");
  if(CheckPointer(a)==POINTER_DYNAMIC) Print("Динамический объект существует и может быть удален");
  else                                 Print("Объект не существует, либо он автоматический");
 }
 
fxsaber:

Und zum Thema Sichtbarkeit.

Fragen wir uns, was klarer ist?

Nun, wenn der Styler es für Sie so formatiert hat :

1 < 2 && 3 < 4;

dann ist es wieder Sache des Stylisten. Ich würde das nie in meinem Code machen, sondern so:

1<2 && 3<4
либо
1 < 2  &&  3 < 4
Grund der Beschwerde: