Um colega de trabalho me mostrou este programa:
#include <iostream>
#include <memory>
struct A {
std::shared_ptr<int> u{ new int };
};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
int main() {
D d;
d = D( d );
std::cout << d.u;
}
que apesar de inicializar shared_ptr
com new int
imprime zero. Demonstração online: https://gcc.godbolt.org/z/n3Kxbc3Pf
Vejo que isso está de alguma forma relacionado à herança de diamante e à classe base virtual comum.
O programa tem algum comportamento indefinido ou está bem formado e o padrão exige a impressão de zero aqui?
d = D( d )
invocaD
o operador de atribuição de movimento definido implicitamente (com uma cópia temporária ded
como fonte de atribuição).[classe.copy.assign]/12 :
Neste caso, se a atribuição da
A
base for realizada mais de uma vez:std::shared_ptr<int>
em um estado movido, ou seja, vazio.shared_ptr
ad.u
, tornando-o vazio também,o que leva ao resultado observado.