Você não especificou um idioma.
No C ++, um construtor deve tomar cuidado ao chamar uma função virtual, pois a função real que está chamando é a implementação da classe. Se for um método virtual puro sem uma implementação, isso será uma violação de acesso.
Um construtor pode chamar funções não virtuais.
Se sua linguagem é Java, em que as funções geralmente são virtuais por padrão, faz sentido que você precise ser extremamente cuidadoso.
O C # parece lidar com a situação da maneira que você esperaria: você pode chamar métodos virtuais em construtores e chama a versão mais final. Portanto, em C # não é um anti-padrão.
Um motivo comum para chamar métodos de construtores é que você possui vários construtores que desejam chamar um método "init" comum.
Observe que os destruidores terão o mesmo problema com os métodos virtuais; portanto, você não pode ter um método de "limpeza" virtual que fica fora do seu destruidor e espere que ele seja chamado pelo destruidor de classe base.
Java e C # não têm destruidores, eles têm finalizadores. Eu não sei o comportamento com Java.
C # parece manipular a limpeza corretamente nesse sentido.
(Observe que, embora Java e C # possuam coleta de lixo, isso gerencia apenas a alocação de memória. Há outra limpeza que seu destruidor precisa fazer para não liberar memória).