Prevent Object Slicing in pass by value mechanism

d_arin100's Avatar author of Prevent Object Slicing in pass by value mechanism
This is an article on Prevent Object Slicing in pass by value mechanism in C.

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;
};
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Nomination for Article of the month - Sep 2009 Started. Nominate this article.
0
shabbir's Avatar, Join Date: Jul 2004
Go4Expert Founder
Nomination Closed and Voting started for Article of the month - Sep 2009. You can vote for this Article
0
rasd123's Avatar
Banned
Thanks for the info, I appreciate it.
0
ewyawa's Avatar, Join Date: Nov 2009
Newbie Member
Good work !
Very cool, looking great so far. Keep going, I wanna see it finished!