class A
{
public:
int i;
A* operator *( const A &Value ) const
{
A* Res = new A;
Res.i = this.i * Value.i;
return(Res);
}
};
voidOnStart()
{
A a, b, c;
a.i = 2;
b.i = 3;
c.i = 5;
A* d = a * b * c;
Print(d.i); // 30delete d;
}
O código mostra claramente que deve haver uma fuga de memória. E é exactamente isso que está a acontecer. No entanto, como escrevê-lo correctamente para poder "multiplicar" os objectos? Tudo é claro com o operador "*=", como é claro no caso de estruturas. Mas com as aulas, como implementar esta simples funcionalidade?
SZZ E este código.
class A
{
private:
A Tmp;
public:
int i;
A* operator *( const A &Value )
{
this.Tmp.i = this.i * Value.i;
return(&Tmp);
}
};
voidOnStart()
{
A a, b, c;
a.i = 2;
b.i = 3;
c.i = 5;
A* d = a * b * c;
Print(d.i); // 30
}
Destrói ME por F7 e mata Terminal por F5. Porque tenho tanta sorte!
Комбинатор: Acima de tudo, claro, mas se a conveniência for mais importante...
Obrigado! Acontece que o objecto de retorno e "=" ao definir um objecto passam por um construtor adicional.
Na verdade, gostaria de ver uma tabela clara algures, quais são os casos chamados construtores (e quais), e quais são os chamados operadores. Neste momento tudo é intuitivo, o que falha, é claro.
Na verdade, gostaria de ver uma tabela algures, onde os construtores são chamados (e quais) e onde os operadores são chamados. Neste momento está tudo ao nível da intuição, e falha, é claro.
Se devolver algo por valor, será atribuído através de copy-constructor (se for do mesmo tipo) se for uma definição ou operador se não for.
voidOnStart()
{
A a, b, c;
a.i = 2;
b.i = 3;
c.i = 5;
A d = a * b * c;
// код аналогичен A d(a * b * c);// будет вызван копи-конструктор.
A e;
e = a * b * c;
// будет вызван оператор =// но копи-конструктор все равно нужен для множественного умноженияPrint(d.i); // 30
}
As linhas destacadas levantam questões. Porque é que os objectos temporários não se despenharam assim que foram utilizados? Ou seja, antes de se produzirem trinta. Tais objectos iriam bater com a minha máquina, uma vez que é suposto lidar com dezenas de milhões de carraças. Cada objecto devorará gigabytes de RAM, e eu não quero ter tais objectos temporários em vez de os matar imediatamente.
As linhas destacadas levantam questões. Porque é que os objectos temporários não se despenharam assim que foram utilizados? Isto é, antes da produção de trinta.
Normalmente, os objectos temporários não são eliminados imediatamente, mas no fim do contexto.
Se quiser uma eliminação rápida, controle o contexto.
voidOnStart()
{
if (true)
{
A a, b, c;
a.i = 2;
b.i = 3;
c.i = 5;
A d;
{
d = a * b * c;
}
Print(d.i); // 30
}
Print("Kill!");
}
No meu novo gráfico, o exemplo só funcionou quando o reiniciei (todos os botões), o que em si mesmo é incompreensível. Mas agora compreendo isto
Com a abertura das negociações, o efeito especificado desaparece (apenas no reinício)
Fez edições à documentação. O problema com o código era que enviar uma ordem de evento do rato para o gráfico é apenas colocar o comando na fila do gráfico. E se esta fila não for processada (por exemplo, ao fim-de-semana), o gráfico não pode receber os eventos especificados. Adicionada nota e exemplo corrigido à descrição do ChartSetInteger:
Nota
A função é assíncrona - isto significa que a função não espera pela execução do comando, enfileirada com sucesso para o gráfico especificado, mas devolve o controlo imediatamente. A propriedade só mudará depois de o comando ter sido processado na fila gráfica. A função ChartRedraw deve ser chamada para executar imediatamente os comandos na fila do gráfico.
Se precisar de alterar imediatamente várias propriedades do gráfico, as funções apropriadas (ChartSetString, ChartSetDouble, ChartSetString) devem ser executadas num bloco de código e depois o ChartRedraw deve ser chamado uma vez.
Para verificar o resultado da execução, pode usar uma função que consulta a propriedade especificada do gráfico (ChartGetInteger, ChartGetDouble, ChartSetString). Note-se que estas funções são síncronas e aguardam o resultado da execução.
Exemplo:
//+------------------------------------------------------------------+ //| Função de iniciação de peritos| //+------------------------------------------------------------------+ nuloOnInit() { //--- activar mensagens sobre o movimento do rato através da janela do gráfico ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1); //--- actualização forçada das propriedades do gráfico garante a prontidão para o tratamento de eventos ChartRedraw(); }
Sem diferença
Quando se digita, parece depender dos números que se digita. Alguns deles não lhe permitem escrever à máquina. E alguns deles têm.
Estranho comportamento... Se escrever um número inteiro inferior a 12 dígitos, pode saltar um total de mais de 14.
Vamos esperar para ver o que os criadores dizem.
O código mostra claramente que deve haver uma fuga de memória. E é exactamente isso que está a acontecer. No entanto, como escrevê-lo correctamente para poder "multiplicar" os objectos? Tudo é claro com o operador "*=", como é claro no caso de estruturas. Mas com as aulas, como implementar esta simples funcionalidade?
SZZ E este código.
Destrói ME por F7 e mata Terminal por F5. Porque tenho tanta sorte!
ZS E este código
Destrói ME em F7 e mata Terminal em F5. Porque é que tenho tanta sorte?!
Provavelmente recorrência infinita e transbordamento da pilha.
Possivelmente recorrência infinita e transbordamento da pilha.
Certamente o problema está no atribuído, mas a causa parece ser mais profunda.
E não deve obviamente haver repetição em tempo de execução.
Por favor, ajude-me a fazer uma coisa simples
Acima de tudo, claro, mas se a conveniência for mais importante...
Obrigado! Acontece que o objecto de retorno e "=" ao definir um objecto passam por um construtor adicional.
Na verdade, gostaria de ver uma tabela clara algures, quais são os casos chamados construtores (e quais), e quais são os chamados operadores. Neste momento tudo é intuitivo, o que falha, é claro.
Na verdade, gostaria de ver uma tabela algures, onde os construtores são chamados (e quais) e onde os operadores são chamados. Neste momento está tudo ao nível da intuição, e falha, é claro.
Se devolver algo por valor, será atribuído através de copy-constructor (se for do mesmo tipo) se for uma definição ou operador se não for.
Se devolver algo por valor, será atribuído através de copy-constructor (se for do mesmo tipo) se for uma definição ou operador se não for.
Claramente declarado, obrigado!
A SZZ preparou o seu código
Resultado
As linhas destacadas levantam questões. Porque é que os objectos temporários não se despenharam assim que foram utilizados? Ou seja, antes de se produzirem trinta. Tais objectos iriam bater com a minha máquina, uma vez que é suposto lidar com dezenas de milhões de carraças. Cada objecto devorará gigabytes de RAM, e eu não quero ter tais objectos temporários em vez de os matar imediatamente.
As linhas destacadas levantam questões. Porque é que os objectos temporários não se despenharam assim que foram utilizados? Isto é, antes da produção de trinta.
Normalmente, os objectos temporários não são eliminados imediatamente, mas no fim do contexto.
Se quiser uma eliminação rápida, controle o contexto.
É verdade, terá de utilizar operador =
No meu novo gráfico, o exemplo só funcionou quando o reiniciei (todos os botões), o que em si mesmo é incompreensível. Mas agora compreendo isto
Fez edições à documentação. O problema com o código era que enviar uma ordem de evento do rato para o gráfico é apenas colocar o comando na fila do gráfico. E se esta fila não for processada (por exemplo, ao fim-de-semana), o gráfico não pode receber os eventos especificados. Adicionada nota e exemplo corrigido à descrição do ChartSetInteger:
Nota
A função é assíncrona - isto significa que a função não espera pela execução do comando, enfileirada com sucesso para o gráfico especificado, mas devolve o controlo imediatamente. A propriedade só mudará depois de o comando ter sido processado na fila gráfica. A função ChartRedraw deve ser chamada para executar imediatamente os comandos na fila do gráfico.
Se precisar de alterar imediatamente várias propriedades do gráfico, as funções apropriadas (ChartSetString, ChartSetDouble, ChartSetString) devem ser executadas num bloco de código e depois o ChartRedraw deve ser chamado uma vez.
Para verificar o resultado da execução, pode usar uma função que consulta a propriedade especificada do gráfico (ChartGetInteger, ChartGetDouble, ChartSetString). Note-se que estas funções são síncronas e aguardam o resultado da execução.
Exemplo:
//+------------------------------------------------------------------+
//| Função de iniciação de peritos|
//+------------------------------------------------------------------+
nuloOnInit()
{
//--- activar mensagens sobre o movimento do rato através da janela do gráfico
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//--- actualização forçada das propriedades do gráfico garante a prontidão para o tratamento de eventos
ChartRedraw();
}