从虚拟方法返回派生对象作为基础

Returning derived object as base from virtual method

基 class 中有一些虚方法 return 相同的基对象(不是指针)。在一些虚拟覆盖中,我想 return 派生对象作为基础。但问题是该方法总是从 returning 派生创建基础对象。这是一个简单的例子:

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

输出:

Derived
Base

如何更正?

由于您 return 按值,return 值是您 return 编辑的表达式的副本。由于 return 类型始终是 Base,因此 Derived 对象被切片。要使多态性起作用,您通常需要一个指针或引用。

尝试使用 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;
}