In general, I agree that it's something to be avoided. But something none of the answers so far have addressed is the possibility that initialization may fail. Constructors cannot fail, so if your constructor allocates memory, or opens a file, or does anything else that may fail, you need a way to tell the caller that an error occurred. If you do the initialization in the constructor, then you need to have a flag that indicates whether or not the initialization succeeded, and then ensure that the caller checks that flag.
If you have a separate init() routine that must be called before anything else works, callers are more likely to check that return code than to call a didInitializationSucceed()
method after creating the object.