da dove, verso dove, cosa e in quali condizioni è stato misurato?
solo OrderSendAsync MODIFY e all'operazione immediatamente successiva 5 sec ????
risultato molto strano, spaventoso, improbabile - dobbiamo ricontrollare i test
Ho misurato il tempo prima e dopo la funzione, ho calcolato la differenza e ho ottenuto 5 secondi. Nei consiglieri di combattimento si misura tutto, in modo da avere più informazioni per risolvere una situazione anomala. Ho visto questo.
Era necessario creare strutture che potessero ricevere regole di azione diverse al loro interno, ma che potessero essere manipolate tra loro come se fossero identiche.
La tecnica utilizzata è stata formalizzata in questo esempio.
Ogni funzione ha il suo indirizzo nel segmento .text.
Ogni funzione membro (metodo) accetta implicitamente questo puntatore come primo parametro.
I metodi statici non accettano questo puntatore e sono essenzialmente uno "zucchero" sintattico, essendo, di fatto, funzioni ordinarie.
Quando si chiama una funzione virtuale, l'indirizzo della funzione eseguibile viene preso dalla tabella delle funzioni virtuali, il cui puntatore è implicitamente contenuto nella classe in cui la funzione virtuale è dichiarata. L'inizializzazione del puntatore alla funzione eseguibile avviene al momento della creazione di un'istanza dell'oggetto; la logica è la seguente (la scrivo in mql apposta perché sia chiara a tutti i neofiti:
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();
}
Naturalmente, nella realtà, non è tutto così, ma il meccanismo di inizializzazione del puntatore alla funzione è esattamente questo. Di conseguenza, non c'è modo, a partire dalla parola "affatto", di farlo nel modo desiderato in un linguaggio compilato.
Il C++ ha questa magia dei template:
#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;
}
Qualsiasi funzione ha il suo indirizzo nel segmento .text.
Ogni funzione membro (metodo) accetta implicitamente questo puntatore come primo parametro.
I metodi statici non accettano questo puntatore e sono essenzialmente uno "zucchero" sintattico, essendo di fatto funzioni ordinarie.
Quando si chiama una funzione virtuale, l'indirizzo della funzione eseguibile viene preso dalla tabella delle funzioni virtuali, il cui puntatore è implicitamente contenuto nella classe in cui la funzione virtuale è dichiarata. L'inizializzazione del puntatore alla funzione eseguibile avviene al momento della creazione di un'istanza dell'oggetto; la logica è la seguente (la scrivo in mql per renderla chiara a tutti i neofiti:
Naturalmente, nella realtà, non è così, ma il meccanismo di inizializzazione del puntatore alla funzione è esattamente questo.
Grazie per la spiegazione dettagliata con un esempio!
Se ti riferisci al mio rammarico per le possibilità delle interfacce. Voglio imporre solo restrizioni sintattiche alle classi/strutture. Cioè, solo in fase di compilazione, come avviene con lo stesso modificatore const. Per l'autocontrollo, insomma.
Non c'è modo, dalla parola "affatto", di fare quello che si vuole in un linguaggio compilato.
Sopra ho scritto una stampella. Volevo avere qualcosa di già costruito per questi casi.
Probabilmente ha inventato una bicicletta, non lo so. Se qualcuno conosce soluzioni più eleganti, è pregato di condividerle.
In precedenza (nelle vecchie versioni del compilatore) era possibile utilizzare una classe prima della sua dichiarazione:
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());
}
Ma ora si ottiene un errore in fase di compilazione:
classe non definita 'A' non può essere usata
Ho trovato due soluzioni per aggirare l'errore.
1. Attraverso la classe base:
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. Attraverso una classe annidata:
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());
}
La seconda soluzione, a mio avviso, è più ottimale della prima.
Si misura la durata e si ottiene il risultato. Mi è successo con TRADE_ACTION_MODIFY.
Da dove, verso dove, cosa e in quali condizioni è stato misurato?
solo OrderSendAsync MODIFY e l'operazione immediatamente successiva è durata 5 secondi.
risultato molto strano, spaventoso e improbabile - dobbiamo ricontrollare i test.
da dove, verso dove, cosa e in quali condizioni è stato misurato?
solo OrderSendAsync MODIFY e all'operazione immediatamente successiva 5 sec ????
risultato molto strano, spaventoso, improbabile - dobbiamo ricontrollare i test
Ho misurato il tempo prima e dopo la funzione, ho calcolato la differenza e ho ottenuto 5 secondi. Nei consiglieri di combattimento si misura tutto, in modo da avere più informazioni per risolvere una situazione anomala. Ho visto questo.
Era necessario creare strutture che potessero ricevere regole di azione diverse al loro interno, ma che potessero essere manipolate tra loro come se fossero identiche.
La tecnica utilizzata è stata formalizzata in questo esempio.
Purtroppo non ho capito perché i linguaggi OOP non hanno interfacce per i metodi statici.
Devo creare questo orrore.
Come lo immaginate?
Ogni funzione ha il suo indirizzo nel segmento .text.
Ogni funzione membro (metodo) accetta implicitamente questo puntatore come primo parametro.
I metodi statici non accettano questo puntatore e sono essenzialmente uno "zucchero" sintattico, essendo, di fatto, funzioni ordinarie.
Quando si chiama una funzione virtuale, l'indirizzo della funzione eseguibile viene preso dalla tabella delle funzioni virtuali, il cui puntatore è implicitamente contenuto nella classe in cui la funzione virtuale è dichiarata. L'inizializzazione del puntatore alla funzione eseguibile avviene al momento della creazione di un'istanza dell'oggetto; la logica è la seguente (la scrivo in mql apposta perché sia chiara a tutti i neofiti:
Naturalmente, nella realtà, non è tutto così, ma il meccanismo di inizializzazione del puntatore alla funzione è esattamente questo. Di conseguenza, non c'è modo, a partire dalla parola "affatto", di farlo nel modo desiderato in un linguaggio compilato.
Il C++ ha questa magia dei template:
Qualsiasi funzione ha il suo indirizzo nel segmento .text.
Ogni funzione membro (metodo) accetta implicitamente questo puntatore come primo parametro.
I metodi statici non accettano questo puntatore e sono essenzialmente uno "zucchero" sintattico, essendo di fatto funzioni ordinarie.
Quando si chiama una funzione virtuale, l'indirizzo della funzione eseguibile viene preso dalla tabella delle funzioni virtuali, il cui puntatore è implicitamente contenuto nella classe in cui la funzione virtuale è dichiarata. L'inizializzazione del puntatore alla funzione eseguibile avviene al momento della creazione di un'istanza dell'oggetto; la logica è la seguente (la scrivo in mql per renderla chiara a tutti i neofiti:
Naturalmente, nella realtà, non è così, ma il meccanismo di inizializzazione del puntatore alla funzione è esattamente questo.
Grazie per la spiegazione dettagliata con un esempio!
Qual è la sua idea in merito?
Se ti riferisci al mio rammarico per le possibilità delle interfacce. Voglio imporre solo restrizioni sintattiche alle classi/strutture. Cioè, solo in fase di compilazione, come avviene con lo stesso modificatore const. Per l'autocontrollo, insomma.
Non c'è modo, dalla parola "affatto", di fare quello che si vuole in un linguaggio compilato.
Sopra ho scritto una stampella. Volevo avere qualcosa di già costruito per questi casi.
Forum sul trading, sui sistemi di trading automatizzati e sulla verifica delle strategie di trading
Nuova versione di MetaTrader 5 build 3950: prelievo/riempimento nel terminale e rapporto di trading aggiornato
fxsaber, 2023.09.19 23:25
Come eliminare gli errori?La prima volta __LINE__/__COUNTER__ vengono passati all'interno del markos come testo, la seconda volta come numeri.
Ho trovato due soluzioni per aggirare l'errore.
1. Attraverso la classe base:
2. Attraverso una classe annidata: