简体   繁体   中英

Returning derived object as base from virtual method

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?

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM