As operações de movimentação (como o construtor de movimentação) std::shared_ptrsão baratas , pois basicamente são "indicadores de roubo" (da origem para o destino; para ser mais preciso, todo o bloco de controle de estado é "roubado" da origem para o destino, incluindo as informações da contagem de referência) .
Em vez disso, as operações de cópia ao std::shared_ptrinvocar o aumento da contagem de referência atômica (ou seja, não apenas ++RefCountem um RefCountmembro de dados inteiro , mas, por exemplo, chamando o InterlockedIncrementWindows), que é mais caro do que apenas roubar ponteiros / estado.
Portanto, analisando a dinâmica da contagem de ref deste caso em detalhes:
// shared_ptr<CompilerInvocation> sp;
compilerInstance.setInvocation(sp);
Se você passar sppor valor e tirar uma cópia dentro do CompilerInstance::setInvocationmétodo, você terá:
- Ao inserir o método, o
shared_ptrparâmetro é construído com cópia: ref count incremento atômico .
- Dentro do corpo do método, você copia o
shared_ptrparâmetro no membro de dados: ref count incremento atômico .
- Ao sair do método, o
shared_ptrparâmetro é destruído: ref count decrement atomic .
Você tem dois incrementos atômicos e um decréscimo atômico, para um total de três operações atômicas .
Em vez disso, se você passar o shared_ptrparâmetro por valor e depois std::movedentro do método (conforme feito corretamente no código de Clang), você terá:
- Ao inserir o método, o
shared_ptrparâmetro é construído com cópia: ref count incremento atômico .
- Dentro do corpo do método, você
std::moveo shared_ptrparâmetro no membro de dados: ref count não muda! Você está apenas roubando ponteiros / estado: não há operações caras de contagem atômica de ref.
- Ao sair do método, o
shared_ptrparâmetro é destruído; mas desde que você avançou na etapa 2, não há nada para destruir, pois o shared_ptrparâmetro não está mais apontando para nada. Novamente, nenhum decréscimo atômico acontece neste caso.
Conclusão: neste caso, você obtém apenas um incremento atômico de contagem de ref, ou seja, apenas uma operação atômica .
Como você pode ver, isso é muito melhor do que dois incrementos atômicos mais um decréscimo atômico (para um total de três operações atômicas) para o caso da cópia.