具有智能指针的非虚拟删除器 [英] Nonvirtual deleter with smart pointers

查看:74
本文介绍了具有智能指针的非虚拟删除器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读最新的过载(链接),并决定进行测试第8页上的语句:

I was reading the latest Overload (link) and decided to test out the statement at page 8:


shared_ptr将在范围出口处正确调用B的析构函数,即使
,尽管A的析构函数不是虚拟的。

shared_ptr will properly invoke B’s destructor on scope exit, even though the destructor of A is not virtual.

我正在使用Visual Studio 2013,编译器v120:

I am using Visual Studio 2013, compiler v120:

#include <memory>
#include <iostream>

struct A {
    ~A() { std::cout << "Deleting A"; }
};


struct B : public A
{
    ~B() { std::cout << "Deleting B"; }
};

int main()
{
    std::shared_ptr<A> ptr = std::make_shared<B>();
    ptr.reset();

    return 0;
}

此操作按预期方式进行,并打印出删除BDeleting A

This works as expected and prints out "Deleting BDeleting A"

该文章似乎暗示这也应该与std :: unique_ptr:

The article seems to imply that this should also work with std::unique_ptr:


那里几乎不需要管理您自己的资源,因此抵制
的诱惑,以实现您自己的复制/分配/移动构造/移动
分配/析构函数。

There is almost no need to manage your own resources so resist the temptation to implement your own copy/assign/move construct/move assign/destructor functions.

托管资源可以是您的类定义或类实例的
内部的资源。
围绕标准容器和类模板
重构代码,例如unique_ptr或shared_ptr将使您的代码更具可读性和
的可维护性。

Managed resources can be resources inside your class definition or instances of your classes themselves. Refactoring the code around standard containers and class templates like unique_ptr or shared_ptr will make your code more readable and maintainable.

但是,更改时

    std::shared_ptr<A> ptr = std::make_shared<B>();

    std::unique_ptr<A> ptr = std::make_unique<B>();

程序仅输出删除A

我是否误解了这篇文章,并且该行为是标准所预期的?
是MSVC编译器的错误吗?

Did I misunderstand the article and the behavior is intended by the standard? Is it a bug with the MSVC compiler?

推荐答案

shared_ptr unique_ptr 不同。 make_shared 将在调用时创建一个类型已删除的删除器对象,而与unique_ptr一起,删除器就是该类型的一部分。因此,shared_ptr在调用删除程序时知道真实类型,而 unique_ptr 却不知道。这使得 unique_ptr 的效率更高,这就是为什么采用这种方式实现的原因。

shared_ptr and unique_ptr are different. make_shared will create a type erased deleter object on invocation while with unique_ptr the deleter is part of the type. Therefore the shared_ptr knows the real type when it invokes the deleter but the unique_ptr doesn't. This makes unique_ptr's much more efficient which is why it was implemented this way.

我发现文章a有点误导。我认为用虚函数公开基类的副本构造函数不是一个好建议,这听起来像是很多切片问题。

I find the article a bit misleading actually. I do not consider it to be good advice to expose copy constructors of a base class with virtual functions, sounds like a lot of slicing problems to me.

请考虑以下情况:

struct A{
    virtual void foo(){ std::cout << "base"; };
};
struct B : A{
    virtual void foo(){ std::cout << "derived"; };
};
void bar(A& a){
    a.foo(); //derived
    auto localA = a; //poor matanance porgrammer didn't notice that a is polymorphic
    localA.foo(); //base
}

我个人会提倡非侵入式多态性 http://isocpp.org/blog/2012/12/对于任何新的更高层级,基于价值语义和概念的多态性-sean-parent ,都完全避开了这个问题。

I would personally advocate non-intrusive polymorphism http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent for any new higherarchies, it sidesteps the problem entirely.

这篇关于具有智能指针的非虚拟删除器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆