C++ has one pitfall called “object slicing” alien to most programmers using other object-oriented languages like Java. Object slicing (fruit ninja-style) occurs in various scenarios when copying an instance of a derived class to a variable with the type of (one of) its base class(es), e.g.:
#include <iostream> // we use structs for brevity struct Base { Base() {} virtual void doSomething() { std::cout << "All your Base are belong to us!\n"; } }; struct Derived : public Base { Derived() : Base() {} virtual void doSomething() override { std::cout << "I am derived!\n"; } }; static void performTask(Base b) { b.doSomething(); } int main() { Derived derived; // here all evidence that derived was used to initialise base is lost performTask(derived); // will print "All your Base are belong to us!" }
Many explanations of object slicing deal with the fact, that only parts of the fields of derived classes will be copied on assignment or if a polymorphic object is passed to a function by value. Usually this is ok because most of the time only the static type of the Base class is used further on. Of course you can construct scenarios where this becomes a problem.
I ran into the problem with virtual functions that are sliced off of polymorphic objects, too. That can be hard to track down if you are not aware of the issue. Sadly, I do not know of any compilers that issue warnings or errors when passing/copying polymorphic objects by value.
The fix is easy in most cases: Use naked pointers, smart pointers or references to pass your polymorphic objects around. But it can be really hard to track the issue down. So try to define conventions and coding styles that minimise the risk of sliced objects. Do not avoid using and passing values around just out of fear! Values provide many benefits in correctness and readability and even may improve performance when used with concrete classes.
Edit: Removed excess parameters in contruction of derived
. Thx @LorToso for the comment and the hint at resharper C++!
Resharper C++ as a plugin for Visual Studio 2013 gives a warning when object-slicing occurs.
Oh and by the way, the parameters in the constructor of “derived” are unnecessary in the example. Don’t ask me if it compiles though.
Thanks for your comments! I will take a look at Resharper C++!