1

So far I have done the following work:

class Stamp{
 public:
    virtual std::string GetStampName() const { return "undefined"; }
};
class FooStamp : public Stamp {
 public:
    std::string GetStampName() const override { return "foo-stamp"; }
};

I use it like this:

FooStamp fooStamp;
std::cout << "foo-stamp:" << fooStamp.GetStampName() << std::endl;

const Stamp stamp = fooStamp;
std::cout << "stamp:" << stamp.GetStampName() << std::endl;

The actual output is as follows:

foo-stamp:foo-stamp
stamp:undefined     // expected: foo-stamp

Types converted to base classes are not working. What did i do wrong.

Is there a way to make the override effective also ensure that the object is copied by value.

candycat
  • 435
  • 4
  • 13

1 Answers1

6

You’re experiencing object slicing since a FooStamp object doesn’t fit into a Stamp object, and copying it therefore slices off the subclass parts.

Runtime polymorphism requires the use of references or pointers:

Stamp const& stamp = fooStamp;
std::cout << "stamp:" << stamp.GetStampName() << "\n";

Stamp const* pstamp = & fooStamp;
std::cout << "stamp:" << pstamp->GetStampName() << "\n";

Both work. But beware of lifetime: once fooStamp goes out of scope, so do pointers and references to it.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • I didn’t use the pointer because I was worried about the life time when using it externally. Is there a way to avoid? Is copying by value possible to achieve the above requirements. thanks – candycat Jun 03 '20 at 10:18
  • @MengHanYu Copying polymorphic objects is actually surprisingly hard and there isn’t really a shortcut. That’s why traditional OOP is best avoided in C++ as much as possible (there often better ways anyway). You will need a virtual `clone` function for that. But this method needs to allocate dynamic storage, so you will need to handle lifetime explicitly. In most cases you therefore want to create a `Clone` function that returns a `std::unique_ptr`. – Konrad Rudolph Jun 03 '20 at 10:23
  • @MengHanYu • Object lifetime management in C++ is not a simple subject, because C++ has a lot of options for object life time management. There's no one size fits all, because there are many different scenarios. In the code snippet in your question, `Stamp const&` is the one I'd use. For the general situation, `std::unique_ptr` is an excellent _owning_ smart pointer. – Eljay Jun 03 '20 at 11:29