繁体   English   中英

没有 Object 切片的多态向量 [C++]

[英]Polymorphic Vectors Without Object Slicing [C++]

我正在尝试将一些从基 class 派生的对象存储在std::array (或任何其他容器)中,而不进行 object 切片。

以下代码片段中所需的 output 是:

Hi from child1!
Hi from child2!

和代码:

#include <iostream>
#include <array>
#include <memory>

class Base {
    public:
        void hello() { 
            std::cout << "This shouldn't print\n";
        }
};

class Child1 : public Base {
    public:
        void hello() {
            std::cout << "Hi from child 1!\n";
        }
};

class Child2 : public Base {
    public:
        void hello() {
            std::cout << "Hi from child 2!\n";
        }
};

std::array<std::unique_ptr<Base>, 2> array = {std::make_unique<Child1>(Child1()), std::make_unique<Child2>(Child2()) };
 
int main() {
    for (auto &i : array) {
        i->hello();
    }
}

我实际上从代码中得到的 output 是:

This shouldn't print
This shouldn't print

显然派生对象已经被切片了。 有什么办法可以避免这种情况吗?

提前感谢您提供的任何建议。

显然派生对象已经被切片了。

实际上,不。 他们没有被切片。 您在将基类指针存储到数组中的派生类对象方面做的是正确的。

不,代码没有按照您想要的方式工作,不是因为 object 切片,而是因为您根本没有将hello()标记为Base中的virtual和派生类中的override 因此,当您在循环内调用i->hello()时,不会执行多态分派。

此外,您错误地使用std::make_unique() make_unique<T>()的参数按原样传递给T的构造函数。 在这种情况下,您正在从临时的Child1 / Child2对象复制构造您的Child1 / Child2类,这是没有必要的。 你可以摆脱临时工。

您还缺少Base中的virtual析构函数。 当您的数组超出 scope 并且unique_ptr尝试在其Base*指针上调用delete时,这将导致未定义的行为 只会调用Base析构函数,但不会调用Child1 / Child2析构函数。

试试这个:

#include <iostream>
#include <array>
#include <memory>

class Base {
    public:
        virtual ~Base() = default;

        virtual void hello() { 
            std::cout << "This shouldn't print\n";
        }
};

class Child1 : public Base {
    public:
        void hello() override {
            std::cout << "Hi from child 1!\n";
        }
};

class Child2 : public Base {
    public:
        void hello() override {
            std::cout << "Hi from child 2!\n";
        }
};
 
int main() {
    std::array<std::unique_ptr<Base>, 2> array = {
        std::make_unique<Child1>(),
        std::make_unique<Child2>()
    };

    for (auto &i : array) {
        i->hello();
    }
}

在线演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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