Quero passar um ponteiro compartilhado para uma função. Você pode me ajudar com isso?
Claro, posso ajudar com isso. Suponho que você tenha algum conhecimento da semântica de propriedade em C ++. Isso é verdade?
Sim, estou razoavelmente confortável com o assunto.
Boa.
Ok, só consigo pensar em duas razões para shared_ptrargumentar:
- A função deseja compartilhar a propriedade do objeto;
- A função executa alguma operação que funciona especificamente em
shared_ptrs.
Em qual você está interessado?
Estou procurando uma resposta geral, então estou interessado em ambas. Estou curioso para saber o que você quer dizer no caso nº 2, no entanto.
Exemplos de tais funções incluem std::static_pointer_castcomparadores customizados ou predicados. Por exemplo, se você precisa encontrar todos os shared_ptr únicos de um vetor, você precisa de tal predicado.
Ah, quando a função realmente precisa manipular o próprio ponteiro inteligente.
Exatamente.
Nesse caso, acho que devemos passar por referência.
Sim. E se não mudar o ponteiro, você deseja passar pela referência const. Não há necessidade de copiar, pois você não precisa compartilhar a propriedade. Esse é o outro cenário.
OK, entendi. Vamos falar sobre o outro cenário.
Aquele onde você compartilha a propriedade? Está bem. Como você compartilha a propriedade com shared_ptr?
Ao copiá-lo.
Então a função precisará fazer uma cópia de um shared_ptr, correto?
Obviamente. Então, passo por uma referência a const e copio para uma variável local?
Não, isso é uma pessimização. Se for passado por referência, a função não terá escolha a não ser fazer a cópia manualmente. Se for passado por valor, o compilador escolherá a melhor escolha entre uma cópia e uma movimentação e executará automaticamente. Então, passe por valor.
Bom ponto. Devo me lembrar daquele artigo " Quer velocidade? Passe por valor. " Com mais frequência.
Espere, e se a função armazenar o shared_ptrem uma variável de membro, por exemplo? Isso não seria uma cópia redundante?
A função pode simplesmente mover o shared_ptrargumento para seu armazenamento. Mover a shared_ptré barato porque não altera nenhuma contagem de referência.
Ah, boa ideia.
Mas estou pensando em um terceiro cenário: e se você não quiser manipular shared_ptrnem compartilhar a propriedade?
Nesse caso, shared_ptré completamente irrelevante para a função. Se você deseja manipular a ponta, pegue uma ponta e deixe que os chamadores escolham a semântica de propriedade que desejam.
E devo tomar a ponta por referência ou por valor?
As regras usuais se aplicam. Os indicadores inteligentes não mudam nada.
Passe por valor se vou copiar, passe por referência se quiser evitar uma cópia.
Direito.
Hmm. Acho que você esqueceu mais um cenário. E se eu quiser compartilhar a propriedade, mas apenas dependendo de uma determinada condição?
Ah, um caso interessante. Não espero que isso aconteça com frequência. Mas quando isso acontecer, você pode passar por valor e ignorar a cópia, se não precisar, ou passar por referência e fazer a cópia, se precisar.
Arrisco uma cópia redundante na primeira opção e perco um movimento potencial na segunda. Não posso comer o bolo e ficar com ele também?
Se estiver em uma situação em que isso realmente importa, você pode fornecer duas sobrecargas, uma tomando uma referência de valor constante e outra tomando uma referência de valor r. Um copia, o outro se move. Um modelo de função de encaminhamento perfeito é outra opção.
Acho que isso cobre todos os cenários possíveis. Muito obrigado.
const std::shared_ptr<myClass>& arg1