C ++ Object Link Behavior

Consider the following code segment:

class Window // Base class for C++ virtual function example { public: virtual void Create() // virtual function for C++ virtual function example { cout <<"Base class Window"<<endl; } }; class CommandButton : public Window { public: void Create() { cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl; } }; int main() { Window *button = new CommandButton; Window& aRef = *button; aRef.Create(); // Output: Derived class Command Button - Overridden C++ virtual function Window bRef=*button; bRef.Create(); // Output: Base class Window return 0; } 

Both aRef and bRef get the assigned * button , but why the two outputs are different from each other. What is the difference between assigning a reference type and a non reference type?

+5
c ++ polymorphism virtual-functions object-reference
source share
4 answers

You are facing a slicing problem.

 Window bRef =*button; 

Here bRef is not a link, but an object. When you assign a derived type to bRef, you slice the derived part, leaving you only with the Window object created from CommandButton.

What happens is that bRef is created in the above expression using the compiler-created copy constructor for the Window class. All that this constructor does is the RHS copy member elements for the newly created object. Since the class contains no members, nothing happens.

On the side of the note: a class with virtual members must also have a virtual destructor.

+10
source share
  • aRef has a Window static type, but CommandButton dynamic type
  • bRef is just an object of type Window (the CommandButton part is "lost in copy )

It is commonly known as object splitting , and this is usually prevented by creating base classes either abstract (by providing a clean virtual function) or not copying (for example, using boost::noncopyable ), because any solution will make the code not compiled in the Window& aRef = *button; .


Now, why does bRef.Create() call Window::Create ? Well, bRef has nothing more than a Window , so there really isn’t so many alternatives. This essentially looks like declaring a Window and calling Create on it: the fact that bRef was copied from an instance of CommandButton does not matter, because part of the CommandButton was lost in the copy.

I will try to make this clearer by specifying the standard (10.3 / 6):

[Note: the interpretation of a virtual function call depends on the type of object for which it is ( dynamic type ), whereas the interpretation of a non-virtual member function call depends on only the type of pointer or reference designating this object ( static type ) (5.2.2). ]

Only using a pointer or reference can a static type of an object differ from its dynamic type.

+7
source share
 Window bRef=*button; bRef.Create(); // Output: Base class Window 

The static as well as dynamic type of bRef is Window . The virtual mechanism only works with links and pointers. bRef is an object that is not a reference or pointer.

+2
source share
  Window bRef=*button; bRef.Create(); // Output: Base class Window 

Here bRef does not apply to button (you just named it that way). bRef receives only the base subobject, which is equal to Window .

+1
source share

All Articles