有没有一种方法可以强制使用shared_ptr在堆上创建对象

Is there a way to force an object to be created on the heap with shared_ptr?

本文关键字:shared ptr 创建对象 一种 方法 有没有      更新时间:2023-10-16

我想知道是否可以通过创建私有/受保护的描述符并使用shared_ptrs来强制在堆上创建对象,以确保同时进行自动资源管理(shared_ptr的RAII功能)。也许可以用不同的方式来做吗?我之所以这么问,是因为从我在STL听到的(还没有看到)来看,没有虚拟解构函数,所以除了。。。shared_ptr?如果是这样,就没有办法将对象强制到堆中,因为shared_ptr正试图访问destuctor。无论如何要绕过这些限制?

C++是一种将代码的正确性交给程序员的语言。试图通过一些复杂的方法来改变这一点通常会导致代码难以使用或工作不太好。强迫程序员在堆上创建一个对象,即使这对特定情况来说不是"正确的",这也是很糟糕的。如果程序员想开枪打他的脚,就让他开枪吧。

在较大的项目中,代码应该由同行(最好至少有时由更高级的员工)审查其正确性,并遵循项目的编码指南。

我不完全确定"虚拟析构函数"与"安全销毁"answers"共享指针"之间的关系——这是三个关系不太密切的不同概念——当一个类用作基类来派生一个新类时,需要虚拟析构因子。STL对象并不意味着派生自[通常,你使用模板或继承,尽管它们可以组合,但当你这样做时,它会很快变得非常复杂],因此没有必要在STL中使用虚拟析构函数。

如果你有一个基类,并且存储是基于对基类的指针或引用完成的,那么你必须有虚拟析构函数,或者不使用继承。

我认为,"安全销毁"的意思是"没有内存泄漏"[而不是"正确销毁",这当然也可能是一个问题,并导致内存泄漏]。在很多情况下,这意味着"首先不要使用指向对象的指针"。我在SO上看到了很多例子,程序员毫无理由地调用newvector<X>* v = new vector<X>;绝对是一种"臭味"(就像鱼或肉一样,如果气味难闻,代码就会出现问题)。如果您正在调用new,那么使用共享指针、唯一指针或其他"包装"是个好主意。但你不应该强迫这个概念——偶尔也有充分的理由不这么做。

"共享指针"是一个"当对象不再使用时自动销毁它"的概念,这是一种避免内存泄漏的有用技术。

既然我已经告诉你不要这样做了,这里有一种方法可以实现:

class X
{
    private:
       int x; 
       X() : x(42) {}; 
    public:
       static shared_ptr<X> makeX() { return make_shared<X>(); }
};

由于构造函数是私有的,类的"用户"不能调用"new"或创建此类对象。[您可能还想将复制构造函数和赋值运算符设置为私有,或者使用delete来防止它们被使用]。

然而,我仍然认为这首先是一个坏主意。

Mats的回答确实是错误的。make_shared需要一个公共构造函数。但是,以下内容有效:

class X
{
private:
    int x;
    X() : x( 42 ) {};
public:
    static std::shared_ptr<X> makeX()
    {
        return std::shared_ptr<X>( new X() );
    }
};

我不喜欢使用new关键字,但在这种情况下,这是唯一的方法。