You could solve it using a change-if-needed paradigm.
SceneManager::AddActorInRoot(IActor &actor) checks if the actor is already a member of the root list. If it is not, then it adds it to the list and calls IActor::SetParent(this).
SceneManager::RemoveActorFromRoot(IActor &actor) checks if the actor is a member of the root list. If it is not, then we do nothing. Otherwise, we remove it from the list and call IActor::SetParent(null).
Actor::SetParent(SceneManager* new_parent) first checks if the new parent is the same as its current parent. If it is, we return without doing anything. If its current_parent is not null, we call current_parent->RemoveActorFromRoot(*this), then sets current_parent to the new_parent. Then if the new parent is not null, call new_parent->AddActorToRoot(*this).
The loop is not infinite because we recurse only if the requested final state is not the current state. We can call from either end (SetParent or AddActorInRoot/RemoveActorFromRoot) first because either path ends up calling the other if necessary. And as a Java programmer looking back on my C++ days, I strongly suggest using a reference parameter instead of a pointer wherever taking a null pointer as an argument would be 100% unacceptable.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.