与虚拟破坏者相比,Shared_PTR的运行时开销用于子类破坏
Runtime overhead of shared_ptr for subclass destruction compared to virtual destructor
我遇到了在YouTube视频(https://wwwww.youtube.com/watch?v=zingZingwhg5z-o&&&amp(上模仿虚拟破坏者行为的shared_ptr
技巧; index = 6(,在搜索互联网时遇到了此答案:shared_ptr魔术:(
通常,如果B从A继承并具有其自身的驱动器,则我们需要在A基类A中的虚拟破坏者,以确保正确调用B的destuructor。但是,使用shared_ptr
,您可以规避对虚拟破坏者的需求。
由于多态函数中有VTable查找的运行时开销,所以我很好奇shared_ptr
技巧是否可以避免此开销。
首先, unique_ptr
可以使用"技巧"。您只需提供如下。
但是,如果您查看实现,当然会看到它涉及通过功能指针的调用 - 这正是虚拟破坏者在封面下所做的。
虚拟功能调用根本不昂贵。它们只是涉及更多记忆。如果您在紧密的循环中进行此操作,这是唯一的时间表现是一个问题,几乎可以肯定会被缓存。
此外,如果编译器可以证明其知道正确的驱动器,它将完全介绍多态性查找(当然,优化的是(。
长话短说,如果这是您唯一的表现问题,那么您就没有表现问题。如果您有表演问题,并且认为这是因为虚拟破坏者,那么您肯定是错误的。
示例代码:
#include <iostream>
#include <memory>
struct A {
~A() { std::cout << "~An"; }
};
struct B : A {
~B() { std::cout << "~Bn"; }
};
struct poly_deleter {
template<class T>
struct tag {
};
template<class T>
static void delete_it(void *p) { delete reinterpret_cast<T *>(p); }
template<class T>
poly_deleter(tag<T>) : deleter_(&delete_it<T>) {}
void operator()(void *p) const { deleter_(p); }
void (*deleter_)(void *) = nullptr;
};
template<class T> using unique_poly_ptr = std::unique_ptr<T, poly_deleter>;
template<class T, class...Args> auto make_unique_poly(Args&&...args) -> unique_poly_ptr<T>
{
return unique_poly_ptr<T> {
new T (std::forward<Args>(args)...),
poly_deleter(poly_deleter::tag<T>())
};
};
int main()
{
auto pb = make_unique_poly<B>();
auto pa = std::move(pb);
pa.reset();
}
预期输出:
~B
~A
共享ptr类型删除破坏者;各种类型的擦除趋势都具有"相似"的成本;给出或占两个因子。有些节省了缓存或两个遗迹。一种类型的擦除是虚拟函数表。
共享的PTR究竟如何消除破坏。但是,与嵌入式函数调用相比,类型擦除永远不会完全免费。
很难证明这更有效,因为高速缓存的呼气可能比您尝试的任何微型计算标准都要多。在任何一种情况下,它都不太可能是巨大的放缓来源。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 我在c++代码中生成了一个运行时#3异常
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 建议在运行时将带有类实例的列表从c++导入qml
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 在同一模拟中使用静脉和静脉_ inet内容时出现运行时错误
- 读取文件时运行时的未知行为
- 与虚拟破坏者相比,Shared_PTR的运行时开销用于子类破坏
- std::static_pointer_cast是否有任何额外的运行时开销
- 从队列中弹出不同类型的项时的运行时开销
- 如果在保持相同类型的同时添加constness, static_cast运行时开销是多少?
- C++static_cast运行时开销