Overwriting an instance of a subclass with an instance of a superclass

Trying to figure out something (in Hell, actually) I came up with the following code. Why is this legal?

class Superclass {
public:
    virtual void Announce() {
        printf("I am the superclass\n");
    }
};

class Subclass : public Superclass {
public:
    void Announce() {
        printf("I am the subclass\n");
    }
};

int main() {
    Superclass osuper;
    Subclass osub;

    Superclass* p = &osub;
    *p = osuper;
    osub.Announce();

    return 0;
}

In main()I create an instance Subclass, then physically overwrite it with an instance Superclass. Then I successfully call the method Subclasson the rewritten (and so damaged) object.

I can’t directly assign osub = osuper, because it doesn’t make sense, but by going through the pointer I seem to get around this. The above code compiles without warning, but by the time I call osub.Announce(), the memory inside osubno longer contains a valid object Subclass.

It may not be type safe (or even, as is usually safe), but the compiler looks completely happy. Why?

+4
5

= , . , memcpy (p, & osub, sizeof (Superclass)). THAT :)

. http://www.cplusplus.com/articles/y8hv0pDG/

+6

, " ". , , , , , "".

-, operator= -. " ". osub.Announce(); Subclass::Announce, osub Subclass.

Superclass::operator=(Superclass const &);.

Subclass::operator=(Subclass const &); , osuper Subclass const &.

, , , Subclass -, *p = osuper; osub , Subclass.

+2

. , -. , , - :

Subclass& copy(const Superclass& superobject);
+1

, .   SuperClass getSuperClass() {       SuperClass sup;       // sup;   return sup;   }

0

, , : .

, , . . . vtable . , , ( ). ++ 11.

If this violates any of your class hierarchy contracts or in any other way makes no sense to your class hierarchy, then it basically sucks to be you.

The moral of this story: classes should always be inherited from boost::noncopyable.

(I know that the copy constructor was grandfathered from C. This is no excuse.)

0
source

All Articles