My guess is that init is not simply called from the CvUnit constructor (guaranteeing full initialization) due to the close interaction between CvUnit and the FFreeListThrashArray class (I'll abbreviate that as FLTA). It's a pretty strange design pattern to me. Maybe there was also a desire for uniformity with CvPlayer and CvTeam, which exist already on the opening menu and get reset to a blank state when returning there. CvUnit (and CvCity, CvSelectionGroup) are not reusable like that, but still have reset functions (which FLTA does not require and which I've merged into the constructors in AdvCiv). Anyway, I believe the intention is that every unit gets initialized immediately after its creation, and that kill initiates every unit's destruction, even when returning to the opening menu, probably even when returning to the desktop. Within the DLL, nothing will stop a programmer from calling the CvUnitAI constructor directly. CvUnit itself can't be instantiated at all; having to go through CvUnitAI is arguably already counterintuitive enough to make this an unlikely accident. Deleting a CvUnit (or CvUnitAI) pointer is perhaps a slightly more likely mishap. For Python, there's afaik only CyPlayer::initUnit for properly creating a unit. For any game state changes, I'd say it's safe to rely on init and kill; if those aren't executed, the game state will break anyway.
I have some old notes about the life cycle of CvUnit, but they might be too technical: