von wo, wohin, was und unter welchen Bedingungen gemessen wurde?
nur OrderSendAsync MODIFY und zum sofortigen nächsten Vorgang 5 sec ????
sehr seltsames, erschreckendes, unwahrscheinliches Ergebnis - wir müssen die Tests noch einmal überprüfen
Ich habe die Zeit vor und nach der Funktion gemessen, die Differenz berechnet und 5 Sekunden erhalten. Bei Kampfberatern wird alles gemessen, damit es mehr Informationen gibt, um eine anormale Situation zu klären. Ich habe das gesehen.
Es war notwendig, Strukturen zu schaffen, die in ihrem Inneren mit unterschiedlichen Aktionsregeln versehen werden konnten, aber untereinander als identisch manipuliert werden konnten.
Die verwendete Technik wurde an diesem Beispiel formalisiert.
Jede Mitgliedsfunktion (Methode) akzeptiert implizit diesen Zeiger als ihren ersten Parameter.
Statische Methoden akzeptieren diesen Zeiger nicht und sind im Wesentlichen syntaktischer "Zucker", da sie de facto normale Funktionen sind.
Beim Aufruf einer virtuellen Funktion wird die Adresse der ausführbaren Funktion der Tabelle der virtuellen Funktionen entnommen, deren Zeiger implizit in der Klasse enthalten ist, in der die virtuelle Funktion deklariert ist. Die Initialisierung des Zeigers auf die ausführbare Funktion erfolgt bei der Erstellung einer Instanz des Objekts, die Logik ist wie folgt (ich schreibe es absichtlich in mql, damit es für alle Neulinge verständlich ist:
class Base;
class A;
class B;
void FooClassA(Base* p);
void FooClassC(Base* p);
typedefvoid(*_Foo)(Base*);
class Base{
public:
Base(): foo(NULL){}
void Foo() {foo(&this);}
protected:
_Foo foo;
};
class A: public Base{
public:
A():a(100){foo = FooClassA;}
int a;
};
class B: public A{
public:
B():b(-100){}
int b;
};
class C: public B{
public:
C(){foo = FooClassC;}
int Get() {return a+b;}
};
void FooClassA(Base* p){PrintFormat("%s: %i",__FUNCTION__,dynamic_cast<A*>(p).a);}
void FooClassC(Base* p){PrintFormat("%s: %i",__FUNCTION__,dynamic_cast<C*>(p).Get());}
voidOnStart(){
A a;
B b;
C c;
Base* p = &a;
p.Foo();
p=&b;
p.Foo();
p=&c;
p.Foo();
}
Natürlich ist in der Realität nicht alles so, aber der Mechanismus der Initialisierung des Zeigers auf die Funktion ist genau so. Dementsprechend gibt es in einer kompilierten Sprache überhaupt keine Möglichkeit, das so zu machen, wie man es will.
C++ hat eine solche Vorlagenmagie:
#include <iostream>
#include <variant>
struct A
{
int a = 100;
int Get() { return a; }
};
struct B :A
{
int b = -100;
};
struct C :B
{
int Get() { return a + b; }
};
using BaseImpl = std::variant<A, B, C>;
struct Base : BaseImpl
{
using BaseImpl::BaseImpl;
int Get() { return std::visit([](auto&& arg) { return arg.Get(); }, static_cast<BaseImpl&>(*this)); }
};
int main()
{
Base a = A();
Base b = B();
Base c = C();
std::cout << a.Get() << ", " << b.Get() << ", " << c.Get() << std::endl; //100, 100, 0
b = C();
std::cout << a.Get() << ", " << b.Get() << ", " << c.Get() << std::endl; //100, 0, 0return0;
}
Jede Mitgliedsfunktion (Methode) akzeptiert implizit diesen Zeiger als ihren ersten Parameter.
Statische Methoden akzeptieren diesen Zeiger nicht und sind im Wesentlichen syntaktischer "Zucker", da sie de facto normale Funktionen sind.
Beim Aufruf einer virtuellen Funktion wird die Adresse der ausführbaren Funktion aus der Tabelle der virtuellen Funktionen entnommen, deren Zeiger implizit in der Klasse enthalten ist, in der die virtuelle Funktion deklariert ist. Die Initialisierung des Zeigers auf die ausführbare Funktion erfolgt bei der Erstellung einer Instanz des Objekts, die Logik ist wie folgt (ich schreibe es in mql, um es für alle Neulinge verständlich zu machen:
In Wirklichkeit ist es natürlich nicht so, aber der Mechanismus der Initialisierung des Zeigers auf die Funktion ist genau so.
Vielen Dank für die ausführliche Erklärung mit einem Beispiel!
Wenn Sie von meinem Bedauern über die Möglichkeiten von Schnittstellen sprechen. Ich möchte den Klassen/Strukturen nur syntaktische Beschränkungen auferlegen. Das heißt, nur in der Kompilierungsphase, wie es mit dem gleichen const-Modifikator geschieht. Für die Selbstkontrolle, kurz gesagt.
In einer kompilierten Sprache gibt es keine Möglichkeit, das zu tun, was Sie wollen.
Ich habe oben eine Krücke geschrieben. Ich wollte etwas, das für solche Fälle bereits eingebaut ist.
Wahrscheinlich hat er ein Fahrrad erfunden, ich weiß es nicht. Wenn jemand elegantere Lösungen kennt, bitte mitteilen.
Früher (in alten Compiler-Builds) war es möglich, eine Klasse vor ihrer Deklaration zu verwenden:
class A;
class B
{
public: A a;
public: int Val;
};
class A
{
public: B * b;
public: int Test() {return b.Val + 1;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
b.a.b = GetPointer(b);
b.Val = 1;
Print(b.a.Test());
}
Aber jetzt bekommen wir einen Fehler beim Kompilieren:
undefinierte Klasse 'A' kann nicht verwendet werden
Ich habe zwei Lösungen gefunden, um diesen Fehler zu umgehen.
1. Über die Basisklasse:
class A0
{
public: virtualint Test() {return0;}
};
class B
{
public: A0 * a;
public: int Val;
};
class A: public A0
{
public: A(B * source) {b = source;}
public: B * b;
public: virtualint Test() {return b.Val + 1;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
A a(GetPointer(b));
b.a = GetPointer(a);
b.Val = 1;
Print(b.a.Test());
}
2. Über eine verschachtelte Klasse:
class B
{
class A
{
public: B * b;
public: int Test() {return b.Val + 1;}
};
public: A a;
public: int Val;
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
b.a.b = GetPointer(b);
b.Val = 1;
Print(b.a.Test());
}
Die zweite Lösung ist meiner Meinung nach optimaler als die erste.
Sie messen die Dauer und erhalten das Ergebnis. Ich hatte dies auf TRADE_ACTION_MODIFY passieren.
Von wo, bis wo, was und unter welchen Bedingungen wurde gemessen?
nur OrderSendAsync MODIFY und bei der unmittelbar folgenden Operation 5 Sekunden ?
sehr seltsames, beängstigendes, unwahrscheinliches Ergebnis - wir müssen die Tests doppelt überprüfen
von wo, wohin, was und unter welchen Bedingungen gemessen wurde?
nur OrderSendAsync MODIFY und zum sofortigen nächsten Vorgang 5 sec ????
sehr seltsames, erschreckendes, unwahrscheinliches Ergebnis - wir müssen die Tests noch einmal überprüfen
Ich habe die Zeit vor und nach der Funktion gemessen, die Differenz berechnet und 5 Sekunden erhalten. Bei Kampfberatern wird alles gemessen, damit es mehr Informationen gibt, um eine anormale Situation zu klären. Ich habe das gesehen.
Es war notwendig, Strukturen zu schaffen, die in ihrem Inneren mit unterschiedlichen Aktionsregeln versehen werden konnten, aber untereinander als identisch manipuliert werden konnten.
Die verwendete Technik wurde an diesem Beispiel formalisiert.
Leider habe ich nicht verstanden, warum OOP-Sprachen keine Schnittstellen für statische Methoden haben.
Ich muss einen solchen Horror schaffen.
Wie kann man sich das vorstellen?
Jede Funktion hat ihre Adresse im .text-Segment.
Jede Mitgliedsfunktion (Methode) akzeptiert implizit diesen Zeiger als ihren ersten Parameter.
Statische Methoden akzeptieren diesen Zeiger nicht und sind im Wesentlichen syntaktischer "Zucker", da sie de facto normale Funktionen sind.
Beim Aufruf einer virtuellen Funktion wird die Adresse der ausführbaren Funktion der Tabelle der virtuellen Funktionen entnommen, deren Zeiger implizit in der Klasse enthalten ist, in der die virtuelle Funktion deklariert ist. Die Initialisierung des Zeigers auf die ausführbare Funktion erfolgt bei der Erstellung einer Instanz des Objekts, die Logik ist wie folgt (ich schreibe es absichtlich in mql, damit es für alle Neulinge verständlich ist:
Natürlich ist in der Realität nicht alles so, aber der Mechanismus der Initialisierung des Zeigers auf die Funktion ist genau so. Dementsprechend gibt es in einer kompilierten Sprache überhaupt keine Möglichkeit, das so zu machen, wie man es will.
C++ hat eine solche Vorlagenmagie:
Jede Funktion hat ihre Adresse im .text-Segment.
Jede Mitgliedsfunktion (Methode) akzeptiert implizit diesen Zeiger als ihren ersten Parameter.
Statische Methoden akzeptieren diesen Zeiger nicht und sind im Wesentlichen syntaktischer "Zucker", da sie de facto normale Funktionen sind.
Beim Aufruf einer virtuellen Funktion wird die Adresse der ausführbaren Funktion aus der Tabelle der virtuellen Funktionen entnommen, deren Zeiger implizit in der Klasse enthalten ist, in der die virtuelle Funktion deklariert ist. Die Initialisierung des Zeigers auf die ausführbare Funktion erfolgt bei der Erstellung einer Instanz des Objekts, die Logik ist wie folgt (ich schreibe es in mql, um es für alle Neulinge verständlich zu machen:
In Wirklichkeit ist es natürlich nicht so, aber der Mechanismus der Initialisierung des Zeigers auf die Funktion ist genau so.
Vielen Dank für die ausführliche Erklärung mit einem Beispiel!
Wie stellst du dir das vor?
Wenn Sie von meinem Bedauern über die Möglichkeiten von Schnittstellen sprechen. Ich möchte den Klassen/Strukturen nur syntaktische Beschränkungen auferlegen. Das heißt, nur in der Kompilierungsphase, wie es mit dem gleichen const-Modifikator geschieht. Für die Selbstkontrolle, kurz gesagt.
In einer kompilierten Sprache gibt es keine Möglichkeit, das zu tun, was Sie wollen.
Ich habe oben eine Krücke geschrieben. Ich wollte etwas, das für solche Fälle bereits eingebaut ist.
Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien
Neue Version von MetaTrader 5 build 3950: Abhebung/Ausfüllung im Terminal und aktualisierter Handelsbericht
fxsaber, 2023.09.19 23:25
Wie wird man die Fehler los?Beim ersten Mal werden __LINE__/__COUNTER__ innerhalb der Markos als Text übergeben, beim zweiten Mal - Zahlen.
Ich habe zwei Lösungen gefunden, um diesen Fehler zu umgehen.
1. Über die Basisklasse:
2. Über eine verschachtelte Klasse: