0

Say I have an array of pointers to an abstract class:

Piece *pieces[2]; // where piece is an abstract class

And I have two classes that extend Piece called King and Queen. I assign a King to a spot in pieces and Queen to another spot:

pieces[0] = new King();
pieces[1] = new Queen();

If I haven't overloaded the assignment operator, does slicing occur? Or does pieces[0] is an instance of King and pieces[1] is an instance of Queen? What is going on in that array (if this was C++)?

EDIT: See a full example of the code in question here.

Austin Moore
  • 1,414
  • 6
  • 20
  • 43
  • 2
    I can pretend there are no compiler errors, but that doesn't mean I can pretend I know what the resulting code does. Please fix your code to be actual C++. – Benjamin Lindley Mar 11 '12 at 00:18
  • @BenjaminLindley Ok, I changed it to what I think best gives an example of what my question is. I didn't want to portray the wrong question through my code, so originally that's why I tried to make the code just portray the idea without worrying about syntax. – Austin Moore Mar 11 '12 at 00:20
  • You had it half right before. You fixed one thing(removing the dereference (`*`)), but broke another(replacing `new` with `&`). Your code now compiles, but what you're doing is undefined behavior(even if it appears to work). You're creating a temporary object, then storing its address. Don't do that. – Benjamin Lindley Mar 11 '12 at 00:55
  • @BenjaminLindley Just to clarify my understanding of what's going on, does this mean once it's out of scope my pointer is pointing to nothing? – Austin Moore Mar 11 '12 at 00:59
  • 1
    Something like that. And it goes out of scope at the semi-colon. What you want is this: `pieces[0] = new King; pieces[1] = new Queen;` – Benjamin Lindley Mar 11 '12 at 01:01
  • @BenjaminLindley Wow, I didn't know it went out of scope so fast! I'll make sure I avoid doing that in the future and I've change example code to reflect what you suggested. Thank you so much for all your help! – Austin Moore Mar 11 '12 at 01:04
  • 1
    Also remember that since you are using `new`, you need an accompanying `delete`, otherwise you have memory leaks. So when you are done with your objects, you need to do this: `delete pieces[0]; delete pieces[1];` If you used a [smart pointer](http://en.wikipedia.org/wiki/Smart_pointer#C.2B.2B_Smart_Pointers), you could avoid that tedium. – Benjamin Lindley Mar 11 '12 at 01:07

3 Answers3

4

This doesn't actually compile: you can't assign a King * (the type of the expression new King) to a Piece (the type of the expression *pieces[0]).

To answer your implied question, though:

Piece *piece = new King(); // fine, no slicing, just assigning a pointer
*piece = Queen();          // oops, slicing - assigning a Queen to a Piece

In the array in your question, assuming you'd written pieces[0] = new King;, etc., you'd just be storing two Piece pointers, one of which points to a King and one of which points to a Queen.

Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
  • Thank you this is what I was looking for. Sorry about the code not compiling; I am a student and I was just wondering about the concept but I'm still trying to completely understand pointer arrays. I will change the code to make it compile, when I get home where I can test and compile the code, so that others looking at this question in the future wont be confuse. – Austin Moore Mar 11 '12 at 00:36
  • 2
    @AustinMoore: If you have an internet connection, you can always test your code (as long as you stick to the standard library): http://ideone.com/ – Benjamin Lindley Mar 11 '12 at 00:38
  • @BenjaminLindley: Thanks for that link actually :) I use http://www.comeaucomputing.com/tryitout for compiling things online, but it doesn't link or run... – Stuart Golodetz Mar 11 '12 at 00:43
  • @BenjaminLindley Thank you, I did not know about that! I will fix it now then :) – Austin Moore Mar 11 '12 at 00:44
1

No slicing will occur. You're doing pointer assignment, not object assignment.

Pubby
  • 51,882
  • 13
  • 139
  • 180
0

Yes slicing will occur.

Slicing will always occur whenever you are trying to put derived class object to any of its base class. This slicing will become visible if your derived class has added some functionality that your base class do not provide.

Remember, this is the case when you are not following OOP principals. Principal says,

"When you are deriving from any class you should not change the interface. 
The reason for inheritance is moving from generic to specific type, and not
 providing new functionality."

And, if you follow this principal then slicing behaviour can be defined as,

“Moving from specific behaviour to more general behaviour”. 

Slicing through pointer objects are temporary and you can cast the pointer back to derived class to get the original behaviour. Slicing through the object is permanent.

NOTE:- Slicing always does not happen in case of private inheritance. 
If you try to do so it will result in compilation error.
(For more information on private inheritance:-http://stackoverflow.com/questions/19075517/object-slicing-in-private-inheritance/19083420?noredirect=1#19083420)
Bhupesh Pant
  • 4,053
  • 5
  • 45
  • 70