Introduction This article is about the slicing of object while sending the argument through a pass by value mechanism when using polymorphism. Background While we are using passing by address mechanism the address of the base class type as well as the derived class type are same in size. But the object of the derived class is usually bigger than the base class. So while we upcast an object instead of reference or pointer the object will be sliced. Let we have a function which takes an argument as base class type object. Now if we call this function with a derived class object as parameter then the compiler will copy only the base portion of the object the derived portion of the object will be sliced. Code: Derived object before slice Derived object after slice ------------------------------- ------------------------------- Derived vptr Base vptr Member variables of base class Member variables of base class Member variables of derived class Since the compiler knows that a particular type of object will be passed as value so the derived object has been forced to become a base object. When passing by value the copy constructor of the base object will be used and which will initialize the VPTR (Derived object) with the base VTABLE and will copy only the base part of the object. The code Code: #include <iostream> #include <string> using namespace std; class Base { string BaseName; public: Base(const string& basename) : BaseName(basename) {} string Name() { return BaseName; } virtual string Information() { return "We are in " + BaseName; } }; class Derived : public Base { string DerivedName; public: Derived(const string& basename, const string& derivedname) : Base(basename), DerivedName(derivedname) {} string Information() { return DerivedName + "Derive from " + Base::Name(); } }; void CreateSliceObject(Base base) { cout << base.Information() << endl; } int main() { Base base("Animal"); Derived derived("Dog", "Animal"); CreateSliceObject(base); CreateSliceObject(derived); } Now if we declare a function as pure virtual in the base class then the compiler will prevent the object slicing because it will not allow creating an object of base type (This is generally happen for upcast by value). The compiler will show a compilation error and will prevent the object slicing. Code: class Base { string BaseName; public: Base(const string& basename) : BaseName(basename) {} string Name() { return BaseName; } virtual string Information() = 0; };
Nomination Closed and Voting started for Article of the month - Sep 2009. You can vote for this Article