[英]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.