Object slicing trouble

Mar 9, 2016 at 3:00am
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?
Last edited on Mar 9, 2016 at 3:01am
Mar 9, 2016 at 4:29am
Hi,

Edit: the code button working for you guys as well?


http://www.cplusplus.com/articles/jEywvCM9/


I just use the <> button on the formatting menu. The code tags use square brackets and slash at the ending one.

Again, why did it slice?


Not sure why you had different behaviour with almost the same code, but I managed to do this the other day.

Try making A:: functions pure virtual:

virtual void dothis() = 0;
virtual void dothat() = 0;

And the B:: functions ordinary virtual.


Also rule of five (Six), look at the example at the end:

http://en.cppreference.com/w/cpp/language/rule_of_three

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?
Mar 9, 2016 at 5:40am
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.
Mar 9, 2016 at 7:25am
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.

Try making A:: functions pure virtual:

virtual void dothis() = 0;
virtual void dothat() = 0;

And the B:: functions ordinary virtual.


Also rule of five (Six), look at the example at the end:



Okay I'm going to try that out.
Mar 9, 2016 at 2:59pm
> pretending I made 3 cotainer objects and populated contents(...)
¿and if we stop pretending an you show a simplified snip that does exactly that?

> In the real version of this
when posting code, make sure that it does reproduce your problem.
It's pointless to analyse it otherwise.
Topic archived. No new replies allowed.