c++ - 为什么在使用带有指向接口的指针的多态行为时没有调用析构函数?
问题描述
我实现了一个策略设计模式,因此我有一个指向Context
类中接口的指针,因此我可以使用多态性。Strategy
当对象超出范围时,我想调用类的子类和基类析构函数,但是如果我使用指向接口的指针,则不会发生这种情况。
我在类中更改了指向Abstract
类的指针Context
,一切都按预期工作,当实例超出范围时,将调用析构函数。此外,我调试了应用程序并且智能指针正在释放分配的内存,因此我希望调用其他析构函数。
我想知道为什么在指向接口时不调用析构函数,以及保持抽象尽可能高的正确方法是什么。Abstract
接口与不尊重调用层次结构的类有何不同。
我在用着:
- gcc (x86_64-posix-seh-rev0, 由 MinGW-W64 项目构建) 8.1.0
- Win10 x64
- 英特尔酷睿 i7 @2.7GHz
- 16 GB 内存
这是我正在测试的代码:
#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
如您所见,当对象超出范围时,不会调用析构函数。
解决方案
推荐阅读
- openlayers - 在 OpenLayers 5 中合并 WMS 图像切片图层
- kubernetes - 在 kubernetes 部署实现中实现 Liveness 探针时的 Api 版本问题
- eclipse - Eclipse 中无法解析 maven-resources-plugin:2.19.1 依赖 Maven 版本 - 3.6.1
- python-3.x - 如何绘制大的csv文件
- aes - snmp_exporter 是否支持 AES 256,如果支持,那么 snmp.yml 文件结构是什么
- docker - 如何检查来自 tomcat 容器的 catalina.out 日志?
- angular - 在 Angular 上注册自己的 Service Worker 和自己的 Worker
- docker - Docker 不会从容器中输出日志
- django - 在 JSON 响应中包含自动增量字段
- javascript - Tabulator 在运行 mutator 后运行验证器