c++ - 将 shared_ptr 用于不透明类型时的非虚拟析构函数
问题描述
在下面的代码中,Base
是一个带有非虚拟析构函数的抽象基类。
Derived
,一个具体类型,只能在make_thing()
工厂函数内部实例化(它的声明和定义仅在 的范围内可见make_thing()
)。
我的理解是,由于std::shared_ptr<T>
在构造点存储了具体删除器,因此Derived
通过std::shared_ptr<Base>
.
如果make_thing()
返回 astd::unique_ptr<Base>
则不会编译,如果返回 则将是未定义的行为Base*
。
虽然代码按预期工作,但我想知道它是否包含未定义的行为。
#include <iostream>
#include <memory>
class Base {
public:
void method() const noexcept { return this->do_method(); }
protected:
~Base() noexcept { std::cout << "~Base()\n"; }
private:
virtual void do_method() const noexcept = 0;
};
std::shared_ptr<Base> make_thing() {
class Derived final : public Base {
public:
~Derived() noexcept { std::cout << "~Derived()\n"; }
private:
void do_method() const noexcept override {
std::cout << "Derived::do_method()\n";
}
};
return std::make_shared<Derived>();
};
int main() {
// only way to instantiate Derived
auto thing = make_thing();
thing->method();
}
样品运行:
$ clang++ example.cpp -std=c++20
$ ./a.out
Derived::do_method()
~Derived()
~Base()
解决方案
推荐阅读
- android - 阅读短信中的特定单词后打开活动
- java - java.sql.SQLException:无法使用 jdbc.queryForObject 在位置 1(值为 1)设置参数
- java - 如何从可用作自定义实体 ID 生成器中实体 ID 的对象属性生成 UID?
- python - 在 OpenLDAP 中将用户添加到 POSIX 或“memberOf”组
- linux - 如何在不附加的情况下将文本写入 HDFS 中的文件
- powershell - 如何将多行批处理文件语句转换为 Powershell?
- google-analytics - 在 GTM 创建虚拟页面并将其发送到 GA 的问题
- python-3.6 - 为什么 -1*List 对象返回一个空列表?
- sql-server - 签名存储过程和应用程序角色安全冲突
- python - 如何在 docker 容器中使用相机