Um mal ein wenig zurück zu blicken. Wie hat man es denn früher gemacht?
Man hat sich einen Zeiger in einem Objekt erstellt, und entweder Referenzen oder Kopien des Zeigers nach außen zurück gegeben. Hier konnte man sich genauso wenig gegen deletes schützen, die von außen kommen.
Warum also sollte das mit den unique_ptrs anders laufen?
Um deinen Gedanken mal zu betrachten:
Natürlich kann man einen shared_ptr statt unique nutzen, dadurch wird vieles ein wenig robuster, aber verursacht eben auch mehr Overhead. Der weak_ptr muss bei jeder Referenzierung erst einmal prüfen, ob der Zeiger überhaupt noch gültig ist. In den meisten Fällen schiebt man allerdings keine permanenten Zeiger in der Gegend herum, sondern holt sie sich kurz vorher vom Besitzer (zugegeben, das verursacht auch einen gewissen Overhead, allerdings nur einmalig). Möchte man einen perma Zugriff ermöglichen, empfiehlt es sich meiner Meinung nach eher eine ID oder ein Handle zu nutzen und bei Ungültigkeit eine exception zu werfen. So hat man direkt Feedback, wann es denn nicht mehr funktioniert, statt sich später darüber zu wundern warum es an einer Stelle noch funktioniert und an der anderen nicht. In den aller meisten Fällen ist der Besitzer eben sehr offensichtlich zu ermitteln.
Im Übrigen bin ich auch eher ein Fan von unique_ptr und Referenz nach außen hin vergeben. So spart man sich direkt die nullptr checks.