I'm currently investigating the interplay between polymorphic types and assignment operations. My main concern is whether or not someone might try assigning the value of a base class to an object of a derived class, which would cause problems.
From this answer I learned that the assignment operator of the base class is always hidden by the implicitely defined assignment operator of the derived class. So for assignment to a simple variable, incorrect types will cause compiler errors. However, this is not true if the assignment occurs via a reference:
class A { public: int a; };
class B : public A { public: int b; };
int main() {
  A a; a.a = 1;
  B b; b.a = 2; b.b = 3;
  // b = a; // good: won't compile
  A& c = b;
  c = a; // bad: inconcistent assignment
  return b.a*10 + b.b; // returns 13
}
This form of assignment would likely lead to inconcistent object state, however there is no compiler warning and the code looks non-evil to me at first glance.
Is there any established idiom to detect such issues?
I guess I only can hope for run-time detection, throwing an exception if I find such an invalid assignment. The best approach I can think of just now is a user-defined assigment operator in the base class, which uses run-time type information to ensure that this is actually a pointer to an instance of base, not to a derived class, and then does a manual member-by-member copy. This sounds like a lot of overhead, and severely impact code readability. Is there something easier?
Edit: Since the applicability of some approaches seems to depend on what I want to do, here are some details.
I have two mathematical concepts, say ring and field. Every field is a ring, but not conversely. There are several implementations for each, and they share common base classes, namely AbstractRing and AbstractField, the latter derived from the former. Now I try to implement easy-to-write by-reference semantics based on std::shared_ptr. So my Ring class contains a std::shared_ptr<AbstractRing> holding its implementation, and a bunch of methods forwarding to that. I'd like to write Field as inheriting from Ring so I don't have to repeat those methods. The methods specific to a field would simply cast the pointer to AbstractField, and I'd like to do that cast statically. I can ensure that the pointer is actually an AbstractField at construction, but I'm worried that someone will assign a Ring to a Ring& which is actually a Field, thus breaking my assumed invariant about the contained shared pointer.
 
     
    