首页 > 解决方案 > 为什么在使用带有指向接口的指针的多态行为时没有调用析构函数?

问题描述

我实现了一个策略设计模式,因此我有一个指向Context类中接口的指针,因此我可以使用多态性。Strategy当对象超出范围时,我想调用类的子类和基类析构函数,但是如果我使用指向接口的指针,则不会发生这种情况。

我在类中更改了指向Abstract类的指针Context,一切都按预期工作,当实例超出范围时,将调用析构函数。此外,我调试了应用程序并且智能指针正在释放分配的内存,因此我希望调用其他析构函数。

我想知道为什么在指向接口时不调用析构函数,以及保持抽象尽可能高的正确方法是什么。Abstract接口与不尊重调用层次结构的类有何不同。

我在用着:

这是我正在测试的代码:

#include <iostream>
#include <string>
#include <memory>

class StrategyInterface 
{
public:
    virtual void print() = 0;
};

class AbstractStrategy : public StrategyInterface
{
private:
    int a;
public:
    AbstractStrategy();
    virtual ~AbstractStrategy();
    virtual void print() { std::cout << "Printing from Base\n"; }
};

AbstractStrategy::AbstractStrategy()
{
    std::cout << "Calling base constructor\n" ;
}

AbstractStrategy::~AbstractStrategy()
{
    std::cout << "Calling base destructor" ;
}

class ConreteStrategy1 : public AbstractStrategy
{
public:
    ConreteStrategy1()  { std::cout << "Hello from SubClass1 constructor \n"; }
    ~ConreteStrategy1() { std::cout << "Hello from SubClass1 destructor \n"; }
};

class ConreteStrategy2 : public AbstractStrategy
{
public:
     ConreteStrategy2() { std::cout << "Hello from SubClass2 constructor \n"; }
    ~ConreteStrategy2() { std::cout << "Hello from SubClass2 destructor \n"; }
};

class Context
{
public:
    Context(int a) 
    {
        if (a)
        {
            t = std::make_unique<ConreteStrategy1>(); 
            t->print();
        } 
        else
        {
            t = std::make_unique<ConreteStrategy2>();
            t->print();
        }
    } 
    ~Context() = default;
private: 
    std::unique_ptr<StrategyInterface> t;
};

void test()
{
    Context context(0);
}

int main(int argc, char const *argv[])
{
    test();
    return 0;
}

我的预期输出:

Calling base constructor
Hello from SubClass2 constructor
Printing from Base
Hello from SubClass2 destructor
Calling base destructor

注意:当我使用它std::unique_ptr<AbstractStrategy> t;而不是std::unique_ptr<StrategyInterface> t;

我的实际输出:

Calling base constructor 
Hello from SubClass2 constructor
Printing from Base

如您所见,当对象超出范围时,不会调用析构函数。

标签: c++classc++11polymorphismdestructor

解决方案


基类缺少虚拟析构函数,因此缺少未定义的行为。提供一个

virtual ~StrategyInterface() = default;

用于定义的行为。看这里


推荐阅读