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.
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.
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.
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.
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.
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.
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.
2) o construtor de cópias é gerado pelo compilador, a menos que seja declarado pelo utilizador
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.
Alguma sugestão sobre como repará-lo?
Obrigado antecipadamente pela vossa ajuda.
Porque é assim que os operadores =, ==, !=, !&, && e ||| comportam-se sempre em µl quando o ponteiro está à esquerda e o tipo "objecto" está à direita.
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.
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
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.
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:
Resultado: A::A()
e nada mais!
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