Seu colega de trabalho está errado, a maneira comum é e sempre foi colocar o código nos arquivos .cpp (ou em qualquer extensão que você desejar) e nas declarações nos cabeçalhos.
Ocasionalmente, há algum mérito em colocar o código no cabeçalho, isso pode permitir inlining mais inteligente pelo compilador. Mas, ao mesmo tempo, isso pode destruir seus tempos de compilação, pois todo o código deve ser processado toda vez que for incluído pelo compilador.
Por fim, muitas vezes é irritante ter relações com objetos circulares (às vezes desejado) quando todo o código é o cabeçalho.
Bottom line, você estava certo, ele está errado.
Edição: Eu estive pensando sobre sua pergunta. Há um caso em que o que ele diz é verdade. modelos. Muitas bibliotecas "modernas" mais recentes, como o boost, fazem uso pesado de modelos e geralmente são "apenas cabeçalho". No entanto, isso só deve ser feito ao lidar com modelos, pois é a única maneira de fazê-lo ao lidar com eles.
Edição: algumas pessoas gostariam de um pouco mais de esclarecimento, aqui estão algumas reflexões sobre a desvantagem de escrever o código "somente cabeçalho":
Se você pesquisar, verá muitas pessoas tentando encontrar uma maneira de reduzir o tempo de compilação ao lidar com o aumento. Por exemplo: Como reduzir o tempo de compilação com o Boost Asio , que está vendo uma compilação de 14s de um único arquivo 1K com o impulso incluído. Os 14s podem não parecer "explodir", mas certamente são muito mais longos do que o típico e podem aumentar rapidamente. Ao lidar com um grande projeto. As bibliotecas apenas de cabeçalho afetam os tempos de compilação de maneira bastante mensurável. Nós apenas toleramos porque o impulso é muito útil.
Além disso, há muitas coisas que não podem ser feitas apenas nos cabeçalhos (até o boost tem bibliotecas às quais você precisa vincular determinadas partes, como threads, sistema de arquivos, etc.). Um exemplo principal é que você não pode ter objetos globais simples apenas nas bibliotecas de cabeçalho (a menos que recorra à abominação que é um singleton), pois você encontrará erros de definição múltipla. NOTA: As variáveis embutidas do C ++ 17 tornarão esse exemplo específico possível no futuro.
Como ponto final, ao usar o boost como um exemplo de código apenas de cabeçalho, um grande detalhe geralmente é esquecido.
O impulso é uma biblioteca, não um código no nível do usuário. para que não mude com tanta frequência. No código do usuário, se você colocar tudo nos cabeçalhos, cada pequena alteração fará com que você precise recompilar todo o projeto. Isso é um monumental desperdício de tempo (e não é o caso de bibliotecas que não mudam de compilação para compilação). Quando você divide as coisas entre cabeçalho / origem e, melhor ainda, usa declarações de encaminhamento para reduzir inclusões, você pode economizar horas de recompilação quando somadas ao longo de um dia.