Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a possible workaround for object slicing in c++?

Tags:

c++

This is the code:

#include <string>
#include <vector>
#include <iostream>
using namespace std;
class A {
public:
  virtual const string f() const { return "A"; }
};
class B : public A {
public:
  const string f() const { return "B"; }
};
int main(int ac, char** av) {
  vector<A> v;
  v.push_back(B());
  cout << v.at(0).f() << endl;
  return 0;
}

Expected result is B, but it's A. As I understand object slicing is taking place. How to avoid it? Shall I store pointers in vector instead of object instances? Is this the only choice?

like image 952
yegor256 Avatar asked Jun 04 '10 10:06

yegor256


People also ask

What is object slicing and how can we prevent it?

Object slicing can be prevented by making the base class function pure virtual thereby disallowing object creation. It is not possible to create the object of a class that contains a pure virtual method.

What is the syntax of object slicing?

"Slicing" is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is "sliced" away. For example, class A { int foo; }; class B : public A { int bar; }; So an object of type B has two data members, foo and bar .

What is object slicing explain object slicing in context of Upcasting?

Object slicing is defined as the conversion of an object into something with less information (typically a superclass). In C++ it occurs when an object is passed by value and copying the parameter value results in an upcast and it is considered a bad thing, as it may result in very subtle bugs.

Why do we use object slicing?

Object slicing is used to describe the situation when you assign an object of a derived class to an instance of a base class. This causes a loss of methods and member variables for the derived class object. This is termed as information being sliced away.


2 Answers

You need to store pointers. If these refer to dynamically allocated objects, use smart pointers.

like image 102
sbi Avatar answered Oct 13 '22 08:10

sbi


Ordered from most simple, to most complex (but most nice).

Solution 1:

vector<B> v;
v.push_back(B());
cout << v.at(0).f() << endl;

Solution 2:

vector<A*> v;
v.push_back(new B());
cout << v.at(0)->f() << endl;
while(!v.empty()) { delete v.back(); v.pop_back(); }

Solution 3:

vector<boost::shared_ptr<A>> v;
v.push_back(boost::make_shared<B>());
cout << v.at(0)->f() << endl;

If you don't want slicing to happen, you need to take into account the fact that different objects may have different sizes -- ergo you need a solution that can work with variable sizes -- that makes storing on the heap a must.

like image 40
Kornel Kisielewicz Avatar answered Oct 13 '22 07:10

Kornel Kisielewicz