Fehler, Irrtümer, Fragen - Seite 2358

 
Ilya Malev:

Aber auch wenn das Objekt keine virtuellen Methoden hat, sollten Sie die Gültigkeit des Zeigers beim Zugriff darauf überprüfen.

Das ist eigentlich eine zweideutige Frage. Beispielsweise ist diese Prüfung in C# immer vorhanden und in C++ nur bei Bedarf, was einen Geschwindigkeitsvorteil bedeutet.

Wenn man eine Methode aufruft, die nicht auf die Felder eines Objekts zugreift, hat es keinen Sinn, den Zeiger zu überprüfen. Im Grunde genommen ist eine solche Methode gleichbedeutend mit einer statischen Methode.

 
Alexey Navoykov:

Im Allgemeinen ist dies ein zweideutiges Thema. In C# gibt es beispielsweise immer eine solche Prüfung, während sie in C++ nur bei Bedarf erfolgt, was einen Geschwindigkeitsvorteil bedeutet.

Denn wenn man eine Methode ohne Verweis auf die Felder des Objekts aufruft, macht es wirklich keinen Sinn, den Zeiger zu überprüfen. Eine solche Methode ist in der Tat gleichbedeutend mit einer statischen Methode.

Ein Objekt kann überhaupt keine Daten haben, aber es kann ein völlig anderes und kritisch wichtiges Verhalten implementieren, z.B. sich auf einige externe Daten in einer speziellen typabhängigen Weise beziehen oder überhaupt eine spezielle Aktion ausführen. Ich bin mir nicht sicher, wie man einen solchen Ansatz als "Methodenäquivalenz zu statischen (d.h. 100% nicht virtuellen) Methoden in Abwesenheit von Daten" rechtfertigen kann.

Das heißt, zumindest ein Zeigerobjekt hat immer ein Feld - das ist sein Typ. Damit können Sie die Adressen der aufgerufenen Methoden ermitteln. Wozu braucht man sonst überhaupt OOP?

P.S. Obwohl ich persönlich nichts gegen automatische Objekte habe, zumindest eine gewisse Logik des Verhaltens (da ich sie fast nicht benutze), aber dann sollte man nicht zulassen, dass sie Zeigern zugewiesen werden
 

Leider habe ich alle in die Irre geführt, denn die Konstruktionen

B *b=a;
B b=a;

wird der Kopieroperator anstelle des Kopierkonstruktors aufgerufen.
Im zweiten Fall, nachdem der Konstruktor B() aufgerufen wurde

Auf jeden Fall werden wir erst analysieren und dann korrigieren.

 

Oh, es stellt sich heraus, dass µl einen automatisch generierten Kopierkonstruktor hat (ich dachte, es gäbe ihn gar nicht, da man obj(other_obj) nicht klassifizieren kann, nur mit =). Aber warum wird es nicht erzeugt, wenn:

class Q
{
public:
   Q(Q&)=default;  // нельзя
   Q(int) {}       // из-за него копирующий конструктор исчез
};
 
pavlick_:

Oh, es stellt sich heraus, dass µl einen automatisch generierten Kopierkonstruktor hat (ich dachte, es gäbe ihn gar nicht, da man obj(other_obj) nicht klassifizieren kann, nur mit =). Aber warum wird es nicht erzeugt, wenn:

default und delete werden nicht unterstützt.

Wie sich herausstellt, ist der Standard-Kopierkonstruktor bereits fertig.

Nur Kopieroperator, d.h. für Konstrukte:

CFoo foo=another_foo;

Der Standard-CFoo-Konstruktor wird zuerst aufgerufen, und dann wird der Kopieroperator

 
Ilyas:

wird der Kopieroperator aufgerufen, nicht der Kopierkonstruktor.

Aber das ist immer noch ein Fehler, denn der implizite Kopieroperator sollte nur für die Klasse B erstellt werden, nicht für alle Elternklassen, d.h. das Objekt sollte seine Interna nicht teilweise ersetzen dürfen.
 
Ilyas:

default und delete werden nicht unterstützt

Das ist richtig, aber Sie müssen die Generierung des Kopierkonstruktors nur überschreiben, wenn es einen benutzerdefinierten Kopierkonstruktor gibt, nicht wahr? Nicht irgendeine Sonderanfertigung.

 
Alexey Navoykov:
D.h. das Objekt sollte nicht teilweise sein Inneres ersetzen dürfen.

Das ist eine Art künstliche Selbstbeschränkung... Ich würde sogar sagen, Engstirnigkeit.

class A {};
class B : public A {
public:
        void operator =( const A& ) {}
};

Was ist das Problem?

Ich habe ein solches Design in mir selbst gefunden... und es funktioniert... gut. Ich schlage also vor, dass die Entwickler es so lassen, wie es ist... zumindest wenn die entsprechenden Operatoren/Konstruktoren ausdrücklich definiert sind

 
A100:

Das ist eine Art künstliche Selbstbeschränkung... Ich würde sogar sagen, Engstirnigkeit.

Wo liegt das Problem?

Habe ein solches Konstrukt bei mir gefunden... und alles funktioniert... gut. Ich schlage also vor, dass die Entwickler es so lassen, wie es ist... zumindest wenn die entsprechenden Operatoren explizit definiert sind

Prüfen Sie zunächst einmal, wie die Dinge in C++ funktionieren. Offenbar wurden die Regeln von "engstirnigen" Menschen erfunden.

Und um sich jedes Mal vor falscher Spracharchitektur zu schützen, muss man Wobbler schaffen... Nein, man muss es von Anfang an richtig machen. Ich meine die Sprache

 
Alexey Navoykov:

Prüfen Sie zunächst, wie die Dinge in C++ funktionieren. Offenbar wurden die Regeln von "engstirnigen" Menschen erfunden.

Aber jedes Mal Stecker einzubauen, um sich vor einer falschen Spracharchitektur zu schützen... Nein, man muss es von Anfang an richtig machen, ich meine die Sprache.

Speziell für Sie erneut geprüft, unter Berücksichtigung von https://www.mql5.com/ru/forum/1111/page2358#comment_10003995

#ifdef __cplusplus
#include "https://www.mql5.com/ru/forum/1111/page2358#comment_10003995"
void OnStart()
{
        A a;
        B b;
        b = a;
}
#endif

Es ist okay DJ

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2018.12.24
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы