Erros, bugs, perguntas - página 2357

 
Ilya Malev:

Obrigado pela resposta detalhada, no entanto, não compreendo nem um pouco a lógica.

1) Porque é que o compilador vê o B* b1=a construir como uma chamada para copiar o operador A::A(const A&), (em vez de chamar B::B(const A&), porque é a classe B à esquerda do operador=)

2) Porque é que o compilador não gerou o aviso "falta o construtor de cópias"?

3) porque é permitida uma chamada de método "simples" para objectos não existentes (enquanto uma tentativa de chamada A::f() gera directamente um erro de compilação "não uma chamada de método estático")

1) Eu escrevi que este é um erro óbvio que vamos corrigir de qualquer forma

2) o construtor de cópias é gerado pelo compilador, se não for declarado pelo utilizador

3) a questão não é muito clara.
A partir do contexto da discussão:
Poder-se-ia argumentar durante muito tempo sobre se se deve ou não "desreferenciar" um ponteiro se não houver acesso a ele?
A operação de desreferenciação (obter o ponteiro real do cabo) é código "interno" (não personalizado) e caro (em comparação com não o ter).
Porquê executar a desreferenciação se não haverá acesso ao ponteiro?
Enquanto permanecer como está, a operação de desreferenciação é removida pelo optimizador se não houver acesso ao ponteiro.

 
Ilya Malev:

4) E porque é que o compilador permite uma chamada de método virtual "simples"? Penso que a virtualidade não deve depender da presença ou ausência de dados no objecto

Está a confundir a questão.

A chamada desvirtualização é um método de optimização separado que nada tem a ver com a presença ou ausência de campos num objecto.

 
Ilyas:

2) o construtor de cópias é gerado pelo compilador, a menos que seja declarado pelo utilizador

Há um objecto B à esquerda, porque é que o construtor A::A(A&) é chamado (ou gerado) para ele? Isto contradiz os princípios do OOP
 
Alexey Navoykov:
Há o objecto B à esquerda, porque é que o construtor A::A() é chamado a fazê-lo ?

Porque em µl é assim que os operadores =, ==, !=, !&, &| e ||| comportam-se sempre quando há um ponteiro à esquerda e um "objecto" à direita. E, ao mesmo tempo, estes operadores não podem ser sobrecarregados com indicações.

Portanto, por favor, quando corrigir este bug, torne os operadores acima referidos sobrecarregáveis para objectos dinâmicos.

 
Metatrader 4 deixou de funcionar, funciona por um segundo ou mais quando inicio, depois aparece uma janela de negociação com um clique no canto superior esquerdo (Compra/Venda) e depois a aplicação fecha.
Alguma sugestão sobre como repará-lo?
Obrigado antecipadamente pela vossa ajuda.
 
Ilya Malev:

Porque é assim que os operadores =, ==, !=, !&, && e ||| comportam-se sempre em µl quando o ponteiro está à esquerda e o tipo "objecto" está à direita.

O que é que o ponteiro tem a ver com isto? Já vos disse aqui. Aqui funciona da mesma forma sem ponteiro.
 
Alexey Navoykov:
Há o objecto B à esquerda, porque é que o construtor A::A(A&) é chamado (ou gerado) para ele? Isto contradiz os princípios do OOP

Concordo plenamente consigo e já escrevi que se trata de um erro que será corrigido.

Neste caso, o compilador apanhou uma sobrecarga adequada na herança, o que não deveria ter sido feito na construção do objecto.

 
Ilyas:

Pode-se argumentar durante muito tempo sobre se se deve ou não "dereferenciar" um ponteiro se não houver acesso a ele.

A operação de desreferenciação (obtenção de um ponteiro real de um cabo) é código "interno" (não personalizado) e caro (em comparação com não o ter).
Porquê executar a desreferenciação se não haverá acesso ao ponteiro?

Porque uma lista de métodos virtuais faz parte da informação de um objecto, não menos importante do que os próprios dados, e o acesso aos métodos virtuais é o acesso por ponteiro. Por exemplo, se eu escrever no meu exemplo

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

mais uma vez vou obter B::f(), embora este código se refira explicitamente à atribuição do objecto A*, que foi "copiado" de A e foi referenciado por A*. Esta é uma situação mais profunda do que chamar o construtor de cópias "errado". Mas mesmo que o objecto não tivesse tido quaisquer métodos virtuais, deveríamos ter verificado a validade do ponteiro ao aceder ao mesmo.

 
Alexey Navoykov:
Há um objecto B à esquerda, porque é que o construtor A::A(A&) é chamado (ou gerado) para ele ? Isto contradiz os princípios do OOP

Tem a certeza de que existe alguma coisa chamada lá? Fiz o check in x32:

class A {
public:
        A()           { Print(__FUNCSIG__); }
        A( const A& ) { Print(__FUNCSIG__); }
} a;
class B : public A {
public:
        B()           { Print(__FUNCSIG__); }
        B( const B& ) { Print(__FUNCSIG__); }
} *b = a;
void OnStart() {}

Resultado: A::A()
e nada mais!

 
A100:

Tem a certeza de que existe alguma coisa chamada lá? Fiz o check in x32:

Resultado: A::A()
e nada mais!

Por isso, desligados para verificar as lixeiras do gerador/optimizador para pontilhar os I's

Razão: