为什么这个方法不被覆盖?

axe*_*xel 6 c++ polymorphism

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

这是代码的简化,但会产生同样的问题。和 的用法vectorunique_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.


Ted*_*gmo 8

你需要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)