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?
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.
"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 .
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.
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.
You need to store pointers. If these refer to dynamically allocated objects, use smart pointers.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With