Hey guys. Been having some trouble with object slicing, I am failing to understand why. please consider this
<code>
#include <vector>
#include <memory>
class A{
public:
virtual void dothis();
virtual void dothat();
};
class B : public A
{
public:
void dothis();
void dothat();
};
class container
{
public:
std::vector<std::unique_ptr<A>> contents;
};
int main()
{
std::vector<container*> containers;
// pretending I made 3 cotainer objects and populated contents with two instances of class B each
// pretending I detected input
for (int i = 0; i < containers.size(); i++)
{
for (int k = 0; k < containers.at(i)->contents.size(); k++)
{
if (true) // pretending I met the condtion to carry out f(x) dothis()
containers.at(i)->contents.at(k)->dothis(); // In the real version of this it carries out B::dothis(), as is to be expected;
}
}
// pretending I detected another input
for (int i = 0; i < containers.size(); i++)
{
for (int k = 0; k < containers.at(i)->contents.size(); k++)
{
if (true) // pretending I met the condition to carryout f(x) dothat()
containers.at(i)->contents.at(k)->dothat(); // In the real version of this is carries out A::dothat()
// why did it slice???
}
}
}
<endcode>
Again, why did it slice? Maybe the better question is why does one polymorphic f(x) behave as it should but the other doesn't? Thanks in advance
Edit: the code button working for you guys as well?
I call it rule of Six because I had to have a default constructor as well as the the other 5 special member functions defaulted. We need to have this for every polymorphic class.
How did you mange to get your vector of unique pointers? They can't be pushed, did you manage to move them?
With what I did the other day: I didn't try using a shared _pointer , it sounds a lot easier (avoid rule of 5, can push) but there might still be a way using unique ptr. I am quite likely to have had something wrong with my code when trying unique ptr.
I will have to experiment a bit more, but I have an appointment so will try later this evening.
To answer your question(s) I've been doing two ways:
At first I did it this way
1 2 3 4 5 6
class Container
{
addContent(std::unique_ptr<A> a)
{
content.push_back(std::move(a));
}
So yes it was moved. I'd basically call the ctor for A (using std::make_unique) as the parameter and than moved that rvalue. It got quite hard to read without confusion when making the function call.
Then I made this:
1 2 3 4 5 6
addContent(int part1, int part2, char ident)
{
switch(ident){
case youFoundMe:
content.push_back(std::make_unique <B>(part1, part2));
break;}
I about fell over when it let me do it. It's like a weird double ctor to be honest but it helped avoid confusion as to what is actually being passed.