多态指针在 运行 时间发生变化

Polymorphic pointer change at run time

我对多态指针真的很困惑。我有 2 类 从接口派生,如下代码所示。

#include <iostream>

using namespace std;

class Base  {

public:
    virtual ~Base() { }
    virtual void addTest() = 0;
};

class B: public Base {

public:
    B(){}
    ~B(){}

    void addTest(){
        cout << "Add test B\n";
    }
};
class C: public Base {

public:
    C(){}
   ~C(){}

    void addTest(){
        cout << "Add test C\n";
    }
private:   
    void deleteTest(){
        
    }
    
};

int main()
{
    Base *base = new B();
    base->addTest();
    base = new C();
    base->addTest();
    return 0;
}

我想在 运行 时根据条件动态更改指针,以便在不同类型的场景中使用相同的指针。

派生的类各不相同,那么当多态指针对象发生变化时,内存中会发生什么?

如果这种用法不是好的做法,我如何才能在 运行 时动态更改多态指针对象?

更改指针指向的内容完全没问题。 Base* 不是 Base 的实例,它是一个指针 指向 Base 的实例(或派生自它的东西 - - 在这种情况下 BC).

因此在您的代码中,base = new B() 将其设置为指向 B 的新实例,然后 base = new C() 将其设置为指向 [= 的新实例17=].

Derived classes are different from each other, so what happens in memory when the polymorphic pointer object changes?

因为Base* 指向一个Base的实例,所有这一切都在改变哪个实例(或派生实例)Base* 指着。实际上,它只是改变了指针的内存地址。

从那个 Base* 指针,你仍然可以访问那个 Base class 中定义的任何东西——如果函数是定义为 virtual.

如何将其分派到派生类型的确切机制在技术上是语言的 implementation-detail,但通常这是通过称为 double-dispatch 的过程完成的,该过程使用“V-Table”。这是额外的 type-information 与包含 virtual 函数的任何 class 一起存储(它在概念上只是一个 struct 函数指针,其中函数指针由具体类型满足) .

有关 vtable 的更多信息,请参阅:Why do we need a virtual table?


然而,有问题的是这里使用了 newnew 分配必须使用 delete 清理的内存以避免内存泄漏。通过执行以下操作:

Base *base = new B();
base->addTest();
base = new C(); // overwriting base without deleting the old instance
base->addTest();

B 对象的析构函数永远不会 运行,不会清理任何资源,并且永远不会回收 B 本身的内存。这应该是:

Base *base = new B();
base->addTest();
delete base;
base = new C(); // overwriting base without deleting the old instance
base->addTest();
delete base;

或者,更好的是,这应该像 std::unique_ptr 一样使用 smart-pointers 来为您完成此操作。在这种情况下,您不显式使用 newdelete,而是使用 std::make_unique 进行分配,析构函数会自动为您执行此操作:

auto base = std::make_unique<B>();
base->addTest();
base = std::make_unique<C>(); // destroy's the old instance before reassigning
base->addTest();

这是recommended/modern编写动态分配的方式