Erros, bugs, perguntas - página 2356

 
A100:

em C++: A::f()

O que diz este código?

((A*)&b).f();
 
fxsaber:

O que diz este código?

É a mesma coisa.

 
Ilya Malev:

A mesma coisa.

como MQL (assumindo que é convertido para a forma C++). Mas podia tê-lo verificado você mesmo
 
A100:
Isso e MQL (assumindo que é convertido para a forma C++). Mas podia tê-lo verificado você mesmo

Verificado:


 
Ilya Malev:

Verificado:

Penso que está a verificar algo de errado.

B*b1=a;

Tal entrada em MQL significa cópia de um objecto a - para um objecto localizado pelo ponteiro b1. Em geral, é claro que não deve ser compilada.

E para não misturar objectos e apontadores, é melhor usar o prefixo p para apontadores

 
Ilya Malev:

Verificado:

Por favor, não se deixe empenhar por este comportamento mal orientado.

Existem 2 problemas aqui(?):

  1. B *b1=a - um erro explícito, o compilador percebe esta construção como uma chamada do operador de cópia A::A(const A &)

  2. No primeiro caso, o optimizador detectou que A::A(const A &) está vazio, sem membros - sem acesso por "ponteiro" (de facto, não há código para chamar o operador de cópia, tudo foi cortado)
    o B::f() virtual não está sobrecarregado, por isso em vez de uma chamada virtual foi uma simples chamada, B::f() não tem endereço de membro, por isso o acesso por "ponteiro" também foi cortado

    No segundo caso, A::f() é uma tentativa de chamada virtual, há acesso por "ponteiro", mas nenhum objecto a1, porque um construtor de cópias vazio A::A(const A &) também foi chamado para A *a1=b
 
Ilyas:

Por favor, não confie neste comportamento errado.

Existem 2 problemas aqui(?):

Espero que corrija este comportamento erróneo? (cometer um erro de compilação) Porque é possível cometer tal erro por acidente e o compilador não reage de forma alguma.

 
Alexey Navoykov:

Espero que corrija este comportamento erróneo? Porque é possível cometer um tal erro por acidente e o compilador não reage de forma alguma.

Sim, nós vamos arranjá-lo.

A prioridade é definida como baixa porque apenas as classes vazias recebem código de trabalho

 
Ilyas:

Por favor, não confie neste comportamento errado.

Existem 2 problemas aqui(?):

  1. B *b1=a - um erro óbvio, o compilador percebe esta construção como uma chamada ao operador de cópia A::A(const A &)

  2. No primeiro caso, o optimizador determinou que A::A(const A &) está vazio, sem membros - sem acesso por "ponteiro" (de facto, não há código para chamar o operador de cópia, tudo foi cortado)
    o B::f() virtual não está sobrecarregado, por isso em vez de uma chamada virtual foi uma simples chamada, não há endereço de membro em B::f(), por isso o acesso por "ponteiro" também foi cortado

    No segundo caso, A::f() é uma tentativa de chamada virtual, há acesso por "ponteiro", mas nenhum objecto a1, porque um construtor de cópias vazio A::A(const A &) também foi chamado para A *a1=b

Obrigado pela resposta detalhada, no entanto, estou um pouco confuso com a lógica.

1) Porque é que o compilador vê a construção B* b1=a como chamando o operador de cópia 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 B::f() dá directamente um erro de compilação "não uma chamada de método estático")

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

 
Ilya Malev:

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

É exactamente isso. Este é outro bug MQL, que o compilador permite livremente tais coisas: B b = a; Isto é uma violação dos princípios de encapsulamento. Em C++ tais coisas não compilam naturalmente, é necessária uma conversão explícita. E em MQL antigos construtores de MQL tais coisas não eram também permitidas.