In c++ what is object slicing and when does it occur?
18 Answers
"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
.
Then if you were to write this:
B b;
A a = b;
Then the information in b
about member bar
is lost in a
.

- 43,482
- 10
- 63
- 98

- 18,460
- 6
- 41
- 41
-
72Very informative, but see http://stackoverflow.com/questions/274626#274636 for an example of how slicing occurs during method calls (which underscores the danger a little better than the plain assignment example). – Blair Conrad Nov 08 '08 at 13:53
-
67Interesting. I've been programming in C++ for 15 years and this issue never occurred to me, as I've always passed objects by reference as a matter of efficiency and personal style. Goes to show how good habits can help you. – Karl Bielefeldt Feb 02 '11 at 03:48
-
@David : can you explain your line in detail `Then the information in b about member bar is lost in a.` . does foo data gets corrupted after assignment? but why? – Jul 21 '11 at 08:51
-
@Hades: no data gets corrupted. It is just impossible to say `a.bar` because the compiler thinks that `a` is of type `A`. If you cast it back to type `B` then you can retrieve all hidden ("sliced away") fields. – Felix Dombek Aug 12 '11 at 08:24
-
13@Felix Thanks but I don't think casting back (since not a pointer arithmetic) will work , `A a = b;` `a` is now object of type `A` which has copy of `B::foo`. It will be mistake to cast it back now i think. – Aug 12 '11 at 12:27
-
4@Hades: I see what you mean, I was considering pointers. You're right, assignment is not casting of course – in fact, a new object is allocated on the stack. Then `bar` in `b` is not corrupted at all, simply not copied by the compiler-generated assignment operator, so `a` is now a completely new object of type `A` with member `a.foo` set to the same value as `b.foo`. – Felix Dombek Aug 12 '11 at 16:22
-
5@Karl: it does not help in the case of assignment. `B& b = xxx; b = someDerivedClass();` still provoke slicing. It is just that usually the problem goes unnoticed. – Matthieu M. Sep 08 '11 at 17:12
-
2Another answer that explains slicing but not the problem. – Dude Oct 18 '12 at 03:08
-
51This isn't "slicing", or at least a benign variant of it. The real problem occurs if you do `B b1; B b2; A& b2_ref = b2; b2 = b1`. You might think you have copied `b1` to `b2`, but you haven't! You have copied a *part* of `b1` to `b2` (the part of `b1` that `B` inherited from `A`), and left the other parts of `b2` unchanged. `b2` is now a frankensteinian creature consisting of a few bits of `b1` followed by some chunks of `b2`. Ugh! Downvoting because I think the answer is very missleading. – fgp Jan 22 '13 at 14:07
-
33@fgp Your comment should read `B b1; B b2; A& b2_ref = b2; b2_ref = b1` "_The real problem occurs if you_" ... derive from a class with a non-virtual assignment operator. Is `A` even intended for derivation? It has no virtual functions. If you derive from a type, you have to deal with the fact that its member functions can be called! – curiousguy Jun 29 '13 at 14:54
-
A [link](http://www.geeksforgeeks.org/object-slicing-in-c/) with a couple of examples of how to avoid the slicing problem by using pointers or references – pablo_worker Mar 28 '17 at 14:50
-
1@fgp that's why you don't put `B` into a name of reference to `A`. – Euri Pinhollow Oct 26 '17 at 07:43
-
4This answer is wrong. No information is lost here. `a` is capable of holding just one field and gets a copy of this field from `b`. It is never supposed to deal with whatever other fields `b` may have. – user7860670 Mar 12 '18 at 10:12
-
What is the signature of the implicitly-generated copy constructor used in the declaration of `A`? i.e. in `A a = b;`? – user2023370 Jan 20 '21 at 11:44
-
1It's `A(const A&)`. – user2023370 Jan 20 '21 at 12:31
-
@KarlBielefeldt Pass by value isn't a matter of preference or only efficiency. If your function needs a value it can change freely without affecting the caller, you'll have to use pass by value. – user904963 Feb 20 '22 at 19:31
Most answers here fail to explain what the actual problem with slicing is. They only explain the benign cases of slicing, not the treacherous ones. Assume, like the other answers, that you're dealing with two classes A
and B
, where B
derives (publicly) from A
.
In this situation, C++ lets you pass an instance of B
to A
's assignment operator (and also to the copy constructor). This works because an instance of B
can be converted to a const A&
, which is what assignment operators and copy-constructors expect their arguments to be.
The benign case
B b;
A a = b;
Nothing bad happens there - you asked for an instance of A
which is a copy of B
, and that's exactly what you get. Sure, a
won't contain some of b
's members, but how should it? It's an A
, after all, not a B
, so it hasn't even heard about these members, let alone would be able to store them.
The treacherous case
B b1;
B b2;
A& a_ref = b2;
a_ref = b1;
//b2 now contains a mixture of b1 and b2!
You might think that b2
will be a copy of b1
afterward. But, alas, it's not! If you inspect it, you'll discover that b2
is a Frankensteinian creature, made from some chunks of b1
(the chunks that B
inherits from A
), and some chunks of b2
(the chunks that only B
contains). Ouch!
What happened? Well, C++ by default doesn't treat assignment operators as virtual
. Thus, the line a_ref = b1
will call the assignment operator of A
, not that of B
. This is because, for non-virtual functions, the declared (formally: static) type (which is A&
) determines which function is called, as opposed to the actual (formally: dynamic) type (which would be B
, since a_ref
references an instance of B
). Now, A
's assignment operator obviously knows only about the members declared in A
, so it will copy only those, leaving the members added in B
unchanged.
A solution
Assigning only to parts of an object usually makes little sense, yet C++, unfortunately, provides no built-in way to forbid this. You can, however, roll your own. The first step is making the assignment operator virtual. This will guarantee that it's always the actual type's assignment operator which is called, not the declared type's. The second step is to use dynamic_cast
to verify that the assigned object has a compatible type. The third step is to do the actual assignment in a (protected!) member assign()
, since B
's assign()
will probably want to use A
's assign()
to copy A
's, members.
class A {
public:
virtual A& operator= (const A& a) {
assign(a);
return *this;
}
protected:
void assign(const A& a) {
// copy members of A from a to this
}
};
class B : public A {
public:
virtual B& operator= (const A& a) {
if (const B* b = dynamic_cast<const B*>(&a))
assign(*b);
else
throw bad_assignment();
return *this;
}
protected:
void assign(const B& b) {
A::assign(b); // Let A's assign() copy members of A from b to this
// copy members of B from b to this
}
};
Note that, for pure convenience, B
's operator=
covariantly overrides the return type, since it knows that it's returning an instance of B
.
-
1Then the some operations on an object of `A` are not allowed when the object is of type `B`. – curiousguy Jun 29 '13 at 15:05
-
16IMHO, the problem is that there are two different kinds of substitutability that may be implied by inheritance: either any `derived` value may be given to code expecting a `base` value, or any derived reference may be used as a base reference. I would like to see a language with a type system which addresses both concepts separately. There are many cases where a derived reference should be substitutable for a base reference, but derived instances should not be substitutable for base ones; there are also many cases where instances should be convertible but references should not substitute. – supercat Aug 12 '13 at 16:11
-
1Conceptually, in .NET, if a function returns `KeyValuePair
`, one should be able to store that result into a storage location of type `KeyValuePair – supercat Aug 12 '13 at 16:19`, not because an instance of the former is an instance of the latter, but rather because interpreting the return value as a `KVP` would effectively turn it into one. Unfortunately, that would require a separate hierarchy from the normal inheritance one, since a boxed instance of the former type is definitely not equivalent to a boxed instance of the latter. -
28I don't understand what is so bad in your "treacherous" case. You stated that you want to: 1) get a reference to an object of class A and 2) cast the object b1 to class A and copy its stuff to a reference of the class A. What is actually wrong here is the proper logic behind the given code. In other words, you took a small image frame (A), placed it over a bigger image (B) and you painted through that frame, complaining later that your bigger image now looks ugly :) But if we just consider that framed area, it looks pretty good, just as the painter wanted, right? :) – Mladen B. Nov 14 '13 at 13:05
-
15The problem is, differently put, that C++ by default assumes a very strong kind of *substitutability* - it requires the base class'es operations to workly correctly on subclass instances. And that even for operations which the compiler autogenerated like assignment. So it's not enough to not screw up your own operations in this regard, you also have to explicitly disable the wrong ones generated by the compiler. Or of course, stay away from public inheritance, which usually is a good suggestion anway ;-) – fgp Nov 16 '13 at 16:31
-
@supercat I'm a bit unclear on the distinction you're making. Is it 1) transparently passing a derived as a substitute for a base vs 2) opaquely passing a reference to a derived as though it were in fact a reference to a base? – Praxeolitic Jun 17 '14 at 03:30
-
2In .NET, every structure type has an associated heap object type to which it is implicitly convertible. If the structure type implements an interface, methods of that interface may be invoked upon the structure "in place". If one had a structure `FooStruct
` with a field of type `T` implement interface `IFoo – supercat Jun 17 '14 at 03:43` containing property `Foo` of type `T` that could read and write the field, then if `FooStruct ` inherited from `FooStruct `, it should implement `IFoo `, implying that one should be able to store an `Animal` to it. -
Storing a `FooStruct
` into a variable of type `FooStruct – supercat Jun 17 '14 at 03:44` would turn it into a `FooStruct `, which could hold an `Animal` in its field, but casting it to `IFoo ` would turn it into the heap object type associated with `FooStruct `, which would have to implement `IFoo `, but couldn't accept a non-cat `Animal` stored into its property. -
20Another common approach is to simply disable the copy and assignment operator. For classes within inheritance hierarchy, usually there is no reason to use value instead of reference or pointer. – Siyuan Ren Aug 22 '14 at 10:48
-
1@supercat " if FooStruct
inherited from FooStruct – Ark-kun Nov 04 '14 at 18:43". Err, what? How can structure inherit from itself in .Net? You write some very strange things that seem to be not real. -
2@Ark-kun: I was trying to indicate the problem that would occur *if such a thing were allowed*. If there were a means of declaring a structure type which could not be boxed "as its own type" [it could still be "boxed" by storing it into a single-element array], that would make it possible for .NET to support inheritance scenarios which are at present impeded by the fact that for every structure type, the Runtime also effectively defines a heap-object type which has the same inheritance relationships. Any relationships that can't work with heap objects, can't work with structs either. – supercat Nov 04 '14 at 19:30
-
2@Ark-kun It wouldn't inherit from itself, `FooStruct
` and `FooStruct – fgp Nov 05 '14 at 01:15` *aren't* the same type. You can't so such a thing in Java, because the two *are*, as far as the runtime is concerned, the same type. But in e.g. C++, the two are completely distinct types. You should be able to use template specializations to let one specialized type (in this case `FooStruct `) from another (in this case `FooStruct `). Not sure about .NET, though - it *does* have template specialization AFAIK, but not quite as general ones as C++ has, I think. -
20
-
5The "treacherous" case is indeed treacherous and I hadn't considered it before. But what you call "benign" is not benign at all -- nearly 100% of the time, it's a mistake to write this code, and the language should have been designed so that it produces a compilation error. The LSP means that a derived object should *behave* properly when treated as a base-class object, but "behaviour" only means "response to public method calls". The LSP permits *internal state* (what `operator=()` copies) to be arbitrarily redefined in `B`, so copying this to an `A` instance could even produce UB. – j_random_hacker Jul 28 '15 at 14:00
-
2@j_random_hacker I don't agree. The behaviour of C++ is very sensible for a language which has complex by-value types and inheritance. I agree that it might be surprising if you come from a language in which objects always have by-reference behaviour like Java or .NET, but learning about these kinds of things is just part of learning to code effectively in C++. I don't see how `A a = b` could prodce UB that couldn't also happen for `B b2 = b`. – fgp Jul 28 '15 at 14:41
-
3@j_random_hacker For a maybe more convincing argument as to why C++ has to prevent the benign case, consider the signature of A's assignment operator - its `A& operator=(const A&)`. So the only way to avoid that operator being with the argument being an instance of B would be to not automatically cast instances of B to `const A&`. But this *would* interfere with the LSP... – fgp Jul 28 '15 at 16:47
-
2If one or more data members of A are repurposed by B, UB can easily follow from `A a = b`. (You could say that this is bad design/implementation, but it doesn't violate the LSP provided public methods continue to "behave properly", and can often be useful.) As a concrete example, suppose A contains two int members x and y, an int\* p, sets p = &x in its ctor, and requires the expression \*p to be valid at all times. (Maybe other code in A sometimes does p = &y.) B adds a third int member z, and in its ctor sets p = &z. After `A a = b` and b's lifetime ends, a.p no longer points to anything. – j_random_hacker Jul 28 '15 at 17:53
-
1I agree that it's a tricky problem. I think the right way would have been to make a distinction at the type level between types that grant only public access to an object's public methods (and which must therefore obey the LSP) and types that grant access to internal state. Most methods would need to take only the former as parameters (and would thereby be useable with an entire class hierarchy), while assignment operators and copy ctors would require the latter as their parameter (and not obey the LSP). But I may be overlooking things. – j_random_hacker Jul 28 '15 at 18:03
-
-
2@metamorphosis If a is a reference, `a = b` does not make "a" reference object "b" (like "a = &b" would, if "a" were a pointer)! It invokes the assignment operator of the object referenced by "a", which (usually) will proceed to overwrite the referenced object with the contents of object "b". – fgp May 24 '16 at 12:26
-
1Ah I see, yes, this answer explains it well too: http://stackoverflow.com/a/9293732/3454889 – metamorphosis May 25 '16 at 01:16
-
4Many answers here, this one in particular, explains well _what_ object slicing is. But given the popularity of this Q&A, it could be appropriate to also mention that one could avoid this issue altogether by making certain that _non-leaf base classes should be abstract_ (see e.g. Item 33 in Scott Meyers _More Effective C++). – dfrib Jul 08 '16 at 10:22
-
1I performed a test on MSVC 2015, and at the end a_ref is exactly equal to b1. If a_ref is a frankestinian object, is hard to say, because it looks like fully legal reference to an object of type A, with b1 content. – user2286810 Feb 11 '17 at 17:51
-
@user2286810 Sure, if you compare `a_ref` and `b1` as instances of `A`, you won't notice anything because their `A`-part is indeed identical. But if you compare `b1` and `b2`, you will notice that their `A`-part is identical, but whatever members are added by `B` still have their original values. – fgp Feb 21 '17 at 14:33
-
I recently wanted to create a status struct (StatusB) that contained statuses from struct StatusA as well as some aditional statuses. I decided to derive StatusB from StatusA, but could not come up with a way to update StatusB with data from StatusA without writing my own copy constructors. This seems like a neat solution to my problem! – Armandas Aug 18 '17 at 09:24
-
"his is because for non-virtual functions, the declared type (which is A&) determines which function is called" - but only for functions which override base' virtual function and assignment operator in form `T& op=(T&)` is not one of them. – Euri Pinhollow Jan 28 '18 at 23:04
-
@ j_random_hacker: Your example is bad - you have to implement a copy constructor manually for such an `a`, and the obvious implementation that makes `A a1 = a2` safe also makes `A a = b` safe. [see here](https://godbolt.org/z/NwWXhW) – Eric Jun 11 '19 at 08:09
-
this is terrible. i have to manually fix "assign" methods if my class layout changes. – M.kazem Akhgary Sep 28 '19 at 08:22
-
@M.kazemAkhgary Well, that's life. And it's actually not terrible, because you only have to change a class' *own* `assign` method if the class gains a new member. So it's not worse than any other class with overridden assignment or comparison operators, all of which typically must exhaustively handle *all* member variables. – fgp Feb 16 '20 at 11:33
-
This still doesn't show the problem of slicing. You get exactly what you asked for ... You don't have undefined behavior. It might be surprising, yes, but many other things are as well. I think a function call would much better show the problem. – Chris Aug 06 '22 at 07:55
-
@Chris The "problem" with slicing is not that it causes undefined behavior in itself. The problem is that it's a form of non-location interaction of code from different classes that is often not considered when a class hierarchy is designed. Many C++ programmers will assume that to maintain an certain invariant in class `B` it suffices to main that invariant in all non-const members of B itself. But if the invariant makes assumptions about members of a base class A of B that is not enough, because any non-const member of A (like, operator= above) can be used to modify an instance of B. – fgp Aug 23 '22 at 11:24
If You have a base class A
and a derived class B
, then You can do the following.
void wantAnA(A myA)
{
// work with myA
}
B derived;
// work with the object "derived"
wantAnA(derived);
Now the method wantAnA
needs a copy of derived
. However, the object derived
cannot be copied completely, as the class B
could invent additional member variables which are not in its base class A
.
Therefore, to call wantAnA
, the compiler will "slice off" all additional members of the derived class. The result might be an object you did not want to create, because
- it may be incomplete,
- it behaves like an
A
-object (all special behaviour of the classB
is lost).

- 32,488
- 9
- 84
- 95

- 5,022
- 2
- 22
- 37
-
56C++ is __not__ Java! If `wantAnA` (as its name implies!) wants an `A`, then that's what it gets. And an instance of `A`, will, uh, behave like an `A`. How is that surprising? – fgp Jan 22 '13 at 16:39
-
105
-
4@Black: But wantAnA said it *wants* an A, so that's what it gets. It's the same as declaring a function to take an int, passing 0.1, and then complaining that the function receives 0... – fgp Mar 20 '13 at 13:44
-
12@fgp: The behaviour is similar. However, to the average C++ programmer it might be less obvious. As far as I understood the question, nobody is "complaining". It's just about how the compiler handles the situation. Imho, it is better to avoid slicing at all by passing (const) references. – Black Apr 07 '13 at 12:13
-
2@Black: This, IMHO, is dangerous advice. If the value is later copied, passing by reference prevents move semantics from kicking in, because even if the value was a rvalue initially, it'll be an lvalue inside the function. – fgp Apr 12 '13 at 00:33
-
4So you'd throw out inheritance, in favour of 'move' semantics? I'd be surprised at this being considered a general "design preference", frankly. – Thomas W May 07 '13 at 10:01
-
10@ThomasW No, I would not throw out inheritance, but use references. If the signature of wantAnA would be **void wantAnA(const A & myA)**, then there had been not slicing. Instead, a read-only reference to the caller's object is passed. – Black May 28 '13 at 07:44
-
16the problem is mostly on the automatic casting that the compiler performs from `derived` to the type `A`. Implicit casting is always a source of unexpected behavior in C++, because it is often hard to understand from looking at the code locally that a cast took place. – pqnet Aug 06 '14 at 23:15
-
@Black, did you mean "Imho, it's better to avoid slicing at all by passing (const) pointers" rather than "references"? GCC & clang print baseClass twice... #include
using namespace std; struct baseClass { void print() const { cout << "baseClass"; } }; struct derivedClass : public baseClass { void print() const { cout << "derivedClass"; } }; void myFunction(const baseClass& theClass) { theClass.print(); } int main() { baseClass base; myFunction(base); derivedClass derived; myFunction(derived); } – user1902689 May 17 '15 at 05:35 -
3@user1902689 For a function to be overloaded in a derived class, you have to make it "virtual", e.g., virtual void print() const {....} – Black May 18 '15 at 20:12
-
@pqnet it's not a cast. An `A` is constructed at the call site, via a call to `A::A(const A &)` – Caleth Apr 23 '19 at 10:36
-
@Caleth I was referring to the automatic conversion of `const derived&` into `const A&` that happens implicitly when you copy initialise an instance of `A`. My legalese wasn't up to standard 5 years ago so I used to wrote "cast" to identify all conversions, not only the explicit cast expression – pqnet Apr 23 '19 at 16:02
-
@pqnet there is no `B&`, there is no conversion, the (copy constructor's) reference (argument) is bound to the `A` sub-object of the `B` directly. – Caleth Apr 23 '19 at 16:16
-
@Caleth the expression `derived` in the expression `wantAnA(derived)` is an lvalue reference, typed as `B&` because `derived` is an identifier corresponding to a non-const variable of type `B`. The language automatically converts the reference from `B&` into `const A&` as in `const_cast
(static_cast(derived))` which then allows it to invoke `A(A const &)` copy constructor of the `A` class. If such copy constructor is aware of class `B` and tries to infer the actual type of its argument (i.e., by trying to `dynamic_cast – pqnet Apr 23 '19 at 16:46` its argument) it can access the whole `B` object -
1
These are all good answers. I would just like to add an execution example when passing objects by value vs by reference:
#include <iostream>
using namespace std;
// Base class
class A {
public:
A() {}
A(const A& a) {
cout << "'A' copy constructor" << endl;
}
virtual void run() const { cout << "I am an 'A'" << endl; }
};
// Derived class
class B: public A {
public:
B():A() {}
B(const B& a):A(a) {
cout << "'B' copy constructor" << endl;
}
virtual void run() const { cout << "I am a 'B'" << endl; }
};
void g(const A & a) {
a.run();
}
void h(const A a) {
a.run();
}
int main() {
cout << "Call by reference" << endl;
g(B());
cout << endl << "Call by copy" << endl;
h(B());
}
The output is:
Call by reference
I am a 'B'
Call by copy
'A' copy constructor
I am an 'A'

- 836
- 6
- 11
-
Hello. Great answer but I have one question. If I do something like this ** dev d; base* b = &d;** The slicing also takes place? – Adrian Jul 10 '18 at 06:58
-
1@Adrian If you introduce some new member functions or member variables in the derived class then those are not accessible from the base class pointer directly. However you can still access them from inside the overloaded base class virtual functions. See this: https://godbolt.org/z/LABx33 – Vishal Sharma Dec 25 '19 at 14:20
Third match in google for "C++ slicing" gives me this Wikipedia article http://en.wikipedia.org/wiki/Object_slicing and this (heated, but the first few posts define the problem) : http://bytes.com/forum/thread163565.html
So it's when you assign an object of a subclass to the super class. The superclass knows nothing of the additional information in the subclass, and hasn't got room to store it, so the additional information gets "sliced off".
If those links don't give enough info for a "good answer" please edit your question to let us know what more you're looking for.

- 41,321
- 20
- 104
- 134
The slicing problem is serious because it can result in memory corruption, and it is very difficult to guarantee a program does not suffer from it. To design it out of the language, classes that support inheritance should be accessible by reference only (not by value). The D programming language has this property.
Consider class A, and class B derived from A. Memory corruption can happen if the A part has a pointer p, and a B instance that points p to B's additional data. Then, when the additional data gets sliced off, p is pointing to garbage.

- 4,277
- 1
- 23
- 28
-
3
-
2Given: class A { virtual void foo() { } }; class B : A { int *p; void foo() { *p = 3; } }; Now, slice a B when it is assigned to A, call foo(), which calls B::foo(), and voila! Memory corruption assigning through garbage value for B::p. – Walter Bright Nov 08 '08 at 19:28
-
1Yup, Walter is mixing pointer assignment (where A* points to a B object, so B::p is NOT lost) and object assignment (after which A::foo is called). – MSalters Nov 10 '08 at 14:20
-
5I forgot that the copy ctor will reset the vptr, my mistake. But you can still get corruption if A has a pointer, and B sets that to point into B's section that gets sliced off. – Walter Bright Nov 11 '08 at 02:21
-
21This problem isn't just limited to slicing. Any classes that contain pointers are going to have dubious behaviour with a default assignment operator and copy-constructor. – Weeble Feb 11 '09 at 11:54
-
3@Weeble - Which is why you override the default destructor, assignment operator and copy-constructor in these cases. – Bjarke Freund-Hansen Jul 24 '09 at 19:55
-
Polymorphism requires a virtual function or CRTP (templates to make it happen at compile time)... – Dude Oct 18 '12 at 02:32
-
8@Weeble: What makes object slicing worse than general pointer fixups is that to be certain you have prevented slicing from happening, a base class must provide converting constructors *for every derived class*. (Why? Any derived classes that are missed are susceptible to being picked up by the base class's copy ctor, since `Derived` is implicitly convertible to `Base`.) This is obviously counter to the Open-Closed Principle, and a big maintenance burden. – j_random_hacker Oct 24 '12 at 12:30
-
1This is one of most frustrating answers on C++ SO. This has no example, really vague and simply false: slicing normally will not cause "memory corruption" (can you please, elaborate the term?), i do not see a case where it will damage stack, or anything sensitive to execution. It can, however, be a programmer error in his own application, but it is not "corruption". Finally, most assignments like this will be done via pointer, without slicing, the pattern from OP is never discussed in most popular references. – Croll Nov 16 '18 at 20:18
I see all the answers mention when object slicing happens when data members are sliced. Here I give an example that the methods are not overridden:
class A{
public:
virtual void Say(){
std::cout<<"I am A"<<std::endl;
}
};
class B: public A{
public:
void Say() override{
std::cout<<"I am B"<<std::endl;
}
};
int main(){
B b;
A a1;
A a2=b;
b.Say(); // I am B
a1.Say(); // I am A
a2.Say(); // I am A why???
}
B (object b) is derived from A (object a1 and a2). b and a1, as we expect, call their member function. But from polymorphism viewpoint we don’t expect a2, which is assigned by b, to not be overridden. Basically, a2 only saves A-class part of b and that is object slicing in C++.
To solve this problem, a reference or pointer should be used
A& a2=b;
a2.Say(); // I am B
or
A* a2 = &b;
a2->Say(); // I am B

- 32,622
- 4
- 31
- 60

- 3,275
- 4
- 28
- 42
-
`But from polymorphism viewpoint we don’t expect a2, which is assigned by b, to not be overridden. Basically, a2 only saves A-class part of b and that is object slicing in C++.` This doesn't sound right and isn't clear. `a2`'s static type is `A` which is why `A::Say()` was invoked -- I don't think it has to do with object slicing. – MTV Jul 09 '22 at 23:50
In C++, a derived class object can be assigned to a base class object, but the other way is not possible.
class Base { int x, y; };
class Derived : public Base { int z, w; };
int main()
{
Derived d;
Base b = d; // Object Slicing, z and w of d are sliced off
}
Object slicing happens when a derived class object is assigned to a base class object, additional attributes of a derived class object are sliced off to form the base class object.

- 357
- 2
- 11
The slicing problem in C++ arises from the value semantics of its objects, which remained mostly due to compatibility with C structs. You need to use explicit reference or pointer syntax to achieve "normal" object behavior found in most other languages that do objects, i.e., objects are always passed around by reference.
The short answers is that you slice the object by assigning a derived object to a base object by value, i.e. the remaining object is only a part of the derived object. In order to preserve value semantics, slicing is a reasonable behavior and has its relatively rare uses, which doesn't exist in most other languages. Some people consider it a feature of C++, while many considered it one of the quirks/misfeatures of C++.

- 5,790
- 1
- 20
- 21
-
6"_"normal" object behavior_" that's not "normal object behaviour", that's **reference semantic**. And it relates **in no way** with C `struct`, compatibility, or other non-sense the any random OOP priest told you. – curiousguy Nov 27 '11 at 11:27
-
4@curiousguy Amen, brother. It's sad to see how often C++ get bashed from not being Java, when value semantics is one of the things that makes C++ so insanely powerfull. – fgp Jan 22 '13 at 16:42
-
This is not a feature, not a quirk/misfeature. It is normal on-stack-copying behavior, since calling a function with an arg or (same) allocating stack variable of type `Base` must take exactly `sizeof(Base)` bytes in memory, with possible alignment, maybe, that's why "assignment" (on-stack-copy) will not copy derived class members, their offsets are outside sizeof. To avoid "losing data", just use pointer, like anyone else, since pointer memory is fixed in place and size, whereas stack is very volitile – Croll Nov 16 '18 at 20:32
-
1Definitely a misfeature of C++. Assigning a derived object to a base object should be banned, while binding a derived object to a reference or a pointer of the base class should be OK. – John Z. Li May 02 '19 at 09:11
So ... Why is losing the derived information bad? ... because the author of the derived class may have changed the representation such that slicing off the extra information changes the value being represented by the object. This can happen if the derived class if used to cache a representation that is more efficient for certain operations, but expensive to transform back to the base representation.
Also thought someone should also mention what you should do to avoid slicing... Get a copy of C++ Coding Standards, 101 rules guidlines, and best practices. Dealing with slicing is #54.
It suggests a somewhat sophisticated pattern to fully deal with the issue: have a protected copy constructor, a protected pure virtual DoClone, and a public Clone with an assert which will tell you if a (further) derived class failed to implement DoClone correctly. (The Clone method makes a proper deep copy of the polymorphic object.)
You can also mark the copy constructor on the base explicit which allows for explicit slicing if it is desired.

- 5,299
- 4
- 32
- 43
-
3"_You can also mark the copy constructor on the base explicit_" which does **not** help at all. – curiousguy Aug 04 '12 at 22:25
1. THE DEFINITION OF SLICING PROBLEM
If D is a derived class of the base class B, then you can assign an object of type Derived to a variable (or parameter) of type Base.
EXAMPLE
class Pet
{
public:
string name;
};
class Dog : public Pet
{
public:
string breed;
};
int main()
{
Dog dog;
Pet pet;
dog.name = "Tommy";
dog.breed = "Kangal Dog";
pet = dog;
cout << pet.breed; //ERROR
Although the above assignment is allowed, the value that is assigned to the variable pet loses its breed field. This is called the slicing problem.
2. HOW TO FIX THE SLICING PROBLEM
To defeat the problem, we use pointers to dynamic variables.
EXAMPLE
Pet *ptrP;
Dog *ptrD;
ptrD = new Dog;
ptrD->name = "Tommy";
ptrD->breed = "Kangal Dog";
ptrP = ptrD;
cout << ((Dog *)ptrP)->breed;
In this case, none of the data members or member functions of the dynamic variable being pointed to by ptrD (descendant class object) will be lost. In addition, if you need to use functions, the function must be a virtual function.

- 501
- 5
- 6
-
8I understand the "slicing" part, but I don't understand "problem". How is it a problem that some state of `dog` that isn't part of class `Pet` (the `breed` data member) isn't copied in the variable `pet`? The code is is only interested in the `Pet` data members - apparently. Slicing is definitely a "problem" if it is unwanted, but I don't see that here. – curiousguy Feb 18 '12 at 04:18
-
4
-
I suggest pointing out that you will make the string 'breed' eventually leak memory without a virtual destructor (the destructor of 'string' will not be called) when deleting through 'ptrP'... Why is what you show problematic? The fix is mostly proper class design. The problem in this case is that writing down constructors to control visibility when inheriting is tedious and easily forgotten. You won't get anywhere near the danger zone with your code as there is no polymorphism involved or even mentioned (slicing will truncate your object but not make your program crash, here). – Dude Oct 18 '12 at 02:58
-
26-1 This completely fails to explain the actual problem. C++ has value semantics, __not__ reference semantics like Java, so this is all entirely to be expected. And the "fix" really is an example of truely *horrible* C++ code. "Fixing" non-existing problems like this type of slicing by resorting to dynamic allocation is a recipe for buggy code, leaked memory and horrible performance. Note that there *are* cases where slicing is bad, but this answer failes to point them out. Hint: the trouble starts if you assign through *references*. – fgp Jan 22 '13 at 16:35
-
Do you even understand that trying to access member of type that is not defined (`Dog::breed`) is no way an ERROR related to SLICING? – Croll Nov 16 '18 at 20:22
-
1Have to give a -1, This is a compile-time error, not a run-time error, Pet::breed does not exist. – Nicholas Pipitone Sep 16 '20 at 22:20
It seems to me, that slicing isn't so much a problem other than when your own classes and program are poorly architected/designed.
If I pass a subclass object in as a parameter to a method, which takes a parameter of type superclass, I should certainly be aware of that and know the internally, the called method will be working with the superclass (aka baseclass) object only.
It seems to me only the unreasonable expectation that providing a subclass where a baseclass is requested, would somehow result in subclass specific results, would cause slicing to be a problem. Its either poor design in the use of the method or a poor subclass implementation. I'm guessing its usually the result of sacrificing good OOP design in favor of expediency or performance gains.

- 522
- 4
- 9
-
4But remember, Minok, that you're NOT passing in a reference of that object. You're passing a NEW copy of that object, but using the base class to copy it in the process. – Arafangion Dec 22 '10 at 11:06
-
-
1You're right. Good practice is to use abstract base classes or to restrict the access to copy/assignment. However, it's not so easy to spot once it's there and easy to forget to take care of. Calling virtual methods with sliced *this can make mysterious things happen if you get away without an access violation. – Dude Oct 18 '12 at 03:06
-
1I recall from my C++ programming courses in university that there were standing best practices that for every class we created, we were required to write default constructors, copy constructors and assignment operators, as well as a destructor. This way you made sure that copy construction and the like happened the way you needed it to, while writing the class... rather than later on some odd behavior showing up. – Minok Jul 25 '14 at 17:24
OK, I'll give it a try after reading many posts explaining object slicing but not how it becomes problematic.
The vicious scenario that can result in memory corruption is the following:
- Class provides (accidentally, possibly compiler-generated) assignment on a polymorphic base class.
- Client copies and slices an instance of a derived class.
- Client calls a virtual member function that accesses the sliced-off state.

- 583
- 2
- 9
-
If the client calls a virtual method on the (copied-into) base-class object, the virtual method that is called will be the one defined in the base class, not the virtual method defined in the subclass. Or to put it another way, the assignment-operator will not modify the base-class object's vtable-pointer. – Jeremy Friesner Nov 17 '22 at 04:03
Slicing means that the data added by a subclass are discarded when an object of the subclass is passed or returned by value or from a function expecting a base class object.
Explanation: Consider the following class declaration:
class baseclass
{
...
baseclass & operator =(const baseclass&);
baseclass(const baseclass&);
}
void function( )
{
baseclass obj1=m;
obj1=m;
}
As baseclass copy functions don't know anything about the derived only the base part of the derived is copied. This is commonly referred to as slicing.

- 137,073
- 23
- 153
- 219

- 1,254
- 2
- 16
- 31
class A
{
int x;
};
class B
{
B( ) : x(1), c('a') { }
int x;
char c;
};
int main( )
{
A a;
B b;
a = b; // b.c == 'a' is "sliced" off
return 0;
}

- 17
- 1
-
5Would you mind giving some extra details? How does your answer differ from the already posted ones? – Alexis Pigeon Nov 29 '12 at 12:55
-
3
when a derived class object is assigned to a base class object, additional attributes of a derived class object are sliced off (discard) form the base class object.
class Base {
int x;
};
class Derived : public Base {
int z;
};
int main()
{
Derived d;
Base b = d; // Object Slicing, z of d is sliced off
}

- 186
- 1
- 9
When a Derived class Object is assigned to Base class Object, all the members of derived class object is copied to base class object except the members which are not present in the base class. These members are Sliced away by the compiler. This is called Object Slicing.
Here is an Example:
#include<bits/stdc++.h>
using namespace std;
class Base
{
public:
int a;
int b;
int c;
Base()
{
a=10;
b=20;
c=30;
}
};
class Derived : public Base
{
public:
int d;
int e;
Derived()
{
d=40;
e=50;
}
};
int main()
{
Derived d;
cout<<d.a<<"\n";
cout<<d.b<<"\n";
cout<<d.c<<"\n";
cout<<d.d<<"\n";
cout<<d.e<<"\n";
Base b = d;
cout<<b.a<<"\n";
cout<<b.b<<"\n";
cout<<b.c<<"\n";
cout<<b.d<<"\n";
cout<<b.e<<"\n";
return 0;
}
It will generate:
[Error] 'class Base' has no member named 'd'
[Error] 'class Base' has no member named 'e'

- 1,638
- 1
- 12
- 17
-
1Downvoted because that's not a good example. It wouldn't work either if instead of copying d to b, you would use a pointer in which case d and e would still exist but Base doesn't have those members. Your example only shows that you can't access members that the class doesn't have. – Stefan Fabian Mar 29 '19 at 12:33
-
[Why should I not #include
?](https://stackoverflow.com/q/31816095), [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/q/1452721) – phuclv Apr 18 '21 at 11:06
I just ran across the slicing problem and promptly landed here. So let me add my two cents to this.
Let's have an example from "production code" (or something that comes kind of close):
Let's say we have something that dispatches actions. A control center UI for example.
This UI needs to get a list of things that are currently able to be dispatched. So we define a class that contains the dispatch-information. Let's call it Action
. So an Action
has some member variables. For simplicity we just have 2, being a std::string name
and a std::function<void()> f
. Then it has an void activate()
which just executes the f
member.
So the UI gets a std::vector<Action>
supplied. Imagine some functions like:
void push_back(Action toAdd);
Now we have established how it looks from the UI's perspective. No problem so far. But some other guy who works on this project suddenly decides that there are specialized actions that need more information in the Action
object. For what reason ever. That could also be solved with lambda captures. This example is not taken 1-1 from the code.
So the guy derives from Action
to add his own flavour.
He passes an instance of his home-brewed class to the push_back
but then the program goes haywire.
So what happened?
As you might have guessed: the object has been sliced.
The extra information from the instance has been lost, and f
is now prone to undefined behaviour.
I hope this example brings light about for those people who can't really imagine things when talking about A
s and B
s being derived in some manner.

- 1,567
- 14
- 26