为什么不重写此方法?



在我的一个项目中,我遇到了这个问题,多态性似乎不起作用。派生类似乎不会覆盖基类,但也没有错误。

这是对代码的简化,但它会产生相同的问题。vectorunique_ptr的用法与我的项目中相同,我怀疑我对它们的使用是导致问题的原因。

我期待

void print() override 
{ 
printf("B HEJ");
}

覆盖

virtual void print() 
{ 
printf("A HEJ"); 
}

,但事实并非如此。为什么?

以下是完整的源代码:

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

这里有一个错误:

ass.emplace_back(std::make_unique<A>(B()));

这条线创建一个指向A的唯一指针,通过从默认构造的B复制来初始化它。它等同于裸指针的new A(B())

您需要创建一个指向B的唯一指针,因此您的代码应如下所示:

ass.emplace_back(std::make_unique<B>());

在它上面时,不要忘记将虚拟析构函数添加到A.

您需要make_unique<B>并将virtual析构函数添加到基类中。

  • make_unique<B>创建一个unique_ptr<B>,如果B派生自A将被unqiue_ptr<A>接受(移入)。
  • make_unique<A>(B())复制从B构造一个A,对B进行切片(只会复制默认构造BA部分)。
  • 只要保留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();
}

最新更新