Reputation: 2021
There is some virtual method in base class that return same base object (not pointer). In some of virtual overrides I want to return derived object as base. But problem is that method always creates base object from returning derived. Here is simple example:
#include <iostream>
#include <string>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual Base createAlike() { return Base(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
Base createAlike() override { return Derived(); }
};
int main() {
Derived d;
Base d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1.myName();
return 0;
}
that outputs:
Derived
Base
How to correct it?
Upvotes: 0
Views: 310
Reputation: 72401
Since you return by value, the return value is a copy of the expression you returned. And since that return type is always Base
, the Derived
object gets sliced. For polymorphism to work, you generally need a pointer or reference.
Try this using std::unique_ptr
:
#include <iostream>
#include <string>
#include <memory>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual std::unique_ptr<Base> createAlike()
{ return std::make_unique<Base>(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
std::unique_ptr<Base> createAlike() override
{ return std::make_unique<Derived>(); }
};
int main() {
Derived d;
auto d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1->myName();
return 0;
}
Upvotes: 1