Estou tendo um pouco de debate com meu amigo sobre se essas duas práticas são apenas dois lados da mesma moeda ou se uma é realmente melhor.
Temos uma função que pega um parâmetro, preenche um membro dele e o retorna:
Item predictPrice(Item item)
Acredito que, como ele funciona no mesmo objeto que é passado, não faz sentido retornar o item. De fato, se alguma coisa, na perspectiva do chamador, ele confunde os assuntos, pois você poderia esperar que ele retornasse um novo item, o que não acontece.
Ele afirma que isso não faz diferença, e nem importaria se ele criou um novo item e o devolveu. Discordo totalmente, pelos seguintes motivos:
Se você tiver várias referências ao item que passa (ou ponteiros ou o que for), alocar um novo objeto e devolvê-lo é de importância material, pois essas referências estarão incorretas.
Em linguagens gerenciadas sem memória, a função que aloca uma nova instância reivindica a propriedade da memória e, portanto, teríamos que implementar um método de limpeza chamado em algum momento.
Alocar na pilha é potencialmente caro e, portanto, é importante se a função chamada faz isso.
Portanto, acredito que é muito importante poder ver através de uma assinatura de métodos se ele modifica um objeto ou aloca um novo. Como resultado, acredito que, como a função apenas modifica o objeto passado, a assinatura deve ser:
void predictPrice(Item item)
Em todas as bases de código (reconhecidamente bases de código C e C ++, e não Java, que é a linguagem em que estamos trabalhando) com as quais trabalhei, o estilo acima foi essencialmente respeitado e mantido por programadores consideravelmente mais experientes. Ele afirma que, como o tamanho da minha amostra de bases de código e colegas é pequeno em relação a todas as bases de código e colegas possíveis, minha experiência não é um verdadeiro indicador sobre se alguém é superior.
Então, algum pensamento?
Item
é class Item ...
e não typedef ...& Item
, o local, item
já é uma cópia