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

时间:2017-05-01 01:34:44

标签: c++ derived-class virtual-method

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

#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

如何纠正?

1 个答案:

答案 0 :(得分:1)

由于您按值返回,因此返回值是您返回的表达式的副本。由于返回类型始终为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;
}