De onde, para onde, o que e sob quais condições foi medido?
apenas OrderSendAsync MODIFY e a próxima operação imediata 5 segundos ????
resultado muito estranho, assustador e improvável - precisamos verificar novamente os testes
Medi o tempo antes e depois da função, calculei a diferença e obtive 5 segundos. Nos consultores de combate, tudo é medido, para que haja mais informações para resolver uma situação anormal. Vi isso.
Qualquer função tem seu endereço no segmento .text.
Qualquer função membro (método) aceita implicitamente esse ponteiro como seu primeiro parâmetro.
Os métodos estáticos não aceitam esse ponteiro e são essencialmente "açúcar" sintático, sendo, de fato, funções comuns.
Quando uma função virtual é chamada, o endereço da função executável é retirado da tabela de funções virtuais, cujo ponteiro está implicitamente contido na classe em que a função virtual é declarada. A inicialização do ponteiro para a função executável ocorre ao criar uma instância do objeto, e a lógica é a seguinte (escrevi em mql de propósito para que ficasse claro para todos os neófitos:
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, na realidade, nem tudo é assim, mas o mecanismo de inicialização do ponteiro para a função é exatamente assim. Portanto, não há como, a partir da palavra "de forma alguma", fazer isso da forma desejada em uma linguagem compilada.
O C++ tem essa mágica de modelo:
#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;
}
Qualquer função tem seu endereço no segmento .text.
Qualquer função membro (método) aceita implicitamente esse ponteiro como seu primeiro parâmetro.
Os métodos estáticos não aceitam esse ponteiro e são essencialmente "açúcar" sintático, sendo de fato funções comuns.
Quando uma função virtual é chamada, o endereço da função executável é retirado da tabela de funções virtuais, cujo ponteiro está implicitamente contido na classe em que a função virtual é declarada. A inicialização do ponteiro para a função executável ocorre durante a criação de uma instância do objeto, e a lógica é a seguinte (escrevo em mql para deixar claro para todos os neófitos:
Naturalmente, na realidade, não é assim, mas o mecanismo de inicialização do ponteiro para a função é exatamente assim.
Obrigado pela explicação detalhada com um exemplo!
Se estiver se referindo ao meu pesar sobre as possibilidades das interfaces. Quero impor apenas restrições sintáticas a classes/estruturas. Ou seja, somente no estágio de compilação, como acontece com o mesmo modificador const. Para autocontrole, em resumo.
Não há como, a partir da palavra "de forma alguma", fazer o que você deseja em uma linguagem compilada.
Eu escrevi uma muleta acima. Eu queria ter algo já incorporado para esses casos.
Provavelmente inventou uma bicicleta, não sei. Se alguém conhecer soluções mais elegantes, por favor, compartilhe.
Anteriormente (em compilações antigas do compilador), era possível usar uma classe antes de sua declaração:
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());
}
Mas agora recebemos um erro ao compilar:
undefined class 'A' cannot be used
Encontrei duas soluções para contornar esse erro.
1. Por meio da 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. Por meio de uma classe aninhada:
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());
}
A segunda solução, na minha opinião, é mais otimizada do que a primeira.
Você mede a duração e obtém o resultado. Isso aconteceu em TRADE_ACTION_MODIFY.
De onde, para onde, o que e em que condições foi medido?
apenas OrderSendAsync MODIFY e para a operação imediatamente seguinte, 5 segundos ???
resultado muito estranho, assustador e improvável - precisamos verificar novamente os testes
De onde, para onde, o que e sob quais condições foi medido?
apenas OrderSendAsync MODIFY e a próxima operação imediata 5 segundos ????
resultado muito estranho, assustador e improvável - precisamos verificar novamente os testes
Medi o tempo antes e depois da função, calculei a diferença e obtive 5 segundos. Nos consultores de combate, tudo é medido, para que haja mais informações para resolver uma situação anormal. Vi isso.
Era necessário criar estruturas que pudessem receber diferentes regras de ações em seu interior, mas que fossem manipuladas entre si como idênticas.
A técnica usada foi formalizada neste exemplo.
Infelizmente, eu não entendia por que as linguagens OOP não têm interfaces para métodos estáticos.
Tenho que criar esse horror.
Como você imagina isso?
Qualquer função tem seu endereço no segmento .text.
Qualquer função membro (método) aceita implicitamente esse ponteiro como seu primeiro parâmetro.
Os métodos estáticos não aceitam esse ponteiro e são essencialmente "açúcar" sintático, sendo, de fato, funções comuns.
Quando uma função virtual é chamada, o endereço da função executável é retirado da tabela de funções virtuais, cujo ponteiro está implicitamente contido na classe em que a função virtual é declarada. A inicialização do ponteiro para a função executável ocorre ao criar uma instância do objeto, e a lógica é a seguinte (escrevi em mql de propósito para que ficasse claro para todos os neófitos:
Naturalmente, na realidade, nem tudo é assim, mas o mecanismo de inicialização do ponteiro para a função é exatamente assim. Portanto, não há como, a partir da palavra "de forma alguma", fazer isso da forma desejada em uma linguagem compilada.
O C++ tem essa mágica de modelo:
Qualquer função tem seu endereço no segmento .text.
Qualquer função membro (método) aceita implicitamente esse ponteiro como seu primeiro parâmetro.
Os métodos estáticos não aceitam esse ponteiro e são essencialmente "açúcar" sintático, sendo de fato funções comuns.
Quando uma função virtual é chamada, o endereço da função executável é retirado da tabela de funções virtuais, cujo ponteiro está implicitamente contido na classe em que a função virtual é declarada. A inicialização do ponteiro para a função executável ocorre durante a criação de uma instância do objeto, e a lógica é a seguinte (escrevo em mql para deixar claro para todos os neófitos:
Naturalmente, na realidade, não é assim, mas o mecanismo de inicialização do ponteiro para a função é exatamente assim.
Obrigado pela explicação detalhada com um exemplo!
Qual é a sua ideia sobre isso?
Se estiver se referindo ao meu pesar sobre as possibilidades das interfaces. Quero impor apenas restrições sintáticas a classes/estruturas. Ou seja, somente no estágio de compilação, como acontece com o mesmo modificador const. Para autocontrole, em resumo.
Não há como, a partir da palavra "de forma alguma", fazer o que você deseja em uma linguagem compilada.
Eu escrevi uma muleta acima. Eu queria ter algo já incorporado para esses casos.
Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação
Nova versão do MetaTrader 5 build 3950: Retirada/Preenchimento no terminal e relatório de negociação atualizado
fxsaber, 2023.09.19 23:25
Como se livrar dos erros?Na primeira vez, __LINE__/__COUNTER__ são passados dentro dos marcadores como texto e, na segunda vez, como números.
Encontrei duas soluções para contornar esse erro.
1. Por meio da classe base:
2. Por meio de uma classe aninhada: