在我的一个项目中,我遇到了多态似乎不起作用的问题。派生类似乎不会覆盖基类,但也不会发生错误。
这是代码的简化,但会产生同样的问题。和 的用法vector与unique_ptr我的项目中的相同,我怀疑我对它们的使用是导致问题的原因。
我预计
void print() override
{
printf("B HEJ");
}
Run Code Online (Sandbox Code Playgroud)
覆盖
virtual void print()
{
printf("A HEJ");
}
Run Code Online (Sandbox Code Playgroud)
,但事实并非如此。为什么?
这是完整的源代码:
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class A
{
public:
virtual void print()
{
printf("A HEJ");
}
};
class B : public A
{
public:
void print() override { printf("B HEJ"); }
};
int main()
{
std::vector<std::unique_ptr<A>> ass;
ass.emplace_back(std::make_unique<A>(B()));
ass[0]->print();
std::cin.get();
}
Run Code Online (Sandbox Code Playgroud)
Ser*_*eyA 11
你在这里有一个错误:
ass.emplace_back(std::make_unique<A>(B()));
Run Code Online (Sandbox Code Playgroud)
这一行创建了一个指向 的唯一指针A,通过从 default-constructed 复制来初始化它B。它相当于new A(B())裸指针。
您需要创建一个指向 的唯一指针B,因此您的代码应如下所示:
ass.emplace_back(std::make_unique<B>());
Run Code Online (Sandbox Code Playgroud)
在此期间,不要忘记将虚拟析构函数添加到A.
你需要make_unique<B> 和一个加virtual析构函数的基类。
make_unique<B>创建 a unique_ptr<B>,如果B派生自A将被(移入) a 接受unqiue_ptr<A>。make_unique<A>(B())copyA从 a构造 an B,将其切片B(仅复制A默认构造的部分B)。virtual保留方法链,就会调用最派生的方法。没有virtual析构函数可以确保当你有一个vector基类指针时只调用基类析构函数。结果往往是灾难性的。您希望调用最派生类的析构函数 - 因此创建基类析构函数virtual。#include <iostream>
#include <string>
#include <memory>
#include <vector>
class A
{
public:
virtual ~A() = default;
virtual void print()
{
printf("A HEJ");
}
};
class B : public A
{
public:
void print() override { printf("B HEJ"); }
};
int main()
{
std::vector<std::unique_ptr<A>> ass;
ass.emplace_back(std::make_unique<B>());
ass[0]->print();
}
Run Code Online (Sandbox Code Playgroud)