隐藏shared_ptr实现

Hiding shared_ptr implementations

本文关键字:实现 ptr shared 隐藏      更新时间:2023-10-16

我有一个像这样定义的c++类:

namespace glDetail
{
    class CMesh
    {
    public:
        CMesh(const char* fileName);
         /// some more functions...
         CMesh& operator=(const CMesh& other) = delete;
         CMesh(const CMesh& other) = delete; ///note that assignement operators are disabled ! 
         // That is why I need to use shared_ptrs !
    private:
         /// some member vars...
    };
}
typedef shared_ptr<glDetail::CMesh> Mesh;
shared_ptr CreateMesh(const char* fileName){
    make
}
///main.cpp
int main(int argc, char** args){
     Mesh mesh = CreateMesh("someFileName");
     mesh->Render();
}

是否有一种方法可以隐藏这个实现,而不是调用CreateXXX调用一个适当的构造函数?(也叫->而不是。是混乱…)比如Mesh Mesh = Mesh("someFileName");

问题是只有->可以重载自定义类型,而.则不行。重载->使智能指针类能够提供简单的委托给它们自己对象的成员函数,即简单地写mesh->Render()而不是(*mesh).Render()的能力。

你唯一能做的就是把你的typedef"升级"到一个实际的包装器类,它封装了shared_ptr,并把所有的东西都委托给自己的对象:

class Mesh 
{
    public:
        Mesh(const char* fileName) : ptr(std::make_shared<glDetail::CMesh>(fileName)) {}
        void Render() { ptr->Render(); }
    private:
        std::shared_ptr<glDetail::CMesh> ptr;
};
///main.cpp
int main(int argc, char** args){
     Mesh mesh("someFileName");
     mesh.Render();
}

也调用->而不是。是令人困惑…

没有。它是指针的视觉指示器。我认为这是一件好事。事实上,作为一个c++程序员,如果我看到像Mesh这样的类看起来像一个可以自由创建和复制的值类型,就像它是intstd::string一样,我会非常困惑。您至少应该考虑将其命名为MeshWrapperMeshHolder

Like Mesh Mesh = Mesh("someFileName");

这看起来很像Java。在c++中,语法更简单(见上文)。一些c++专家(如Herb Sutter)提倡的现代替代方案是:

 auto mesh = Mesh { "someFileName" };

事实上,我想知道不使用->的愿望是否也来自Java背景。如果是这样,您应该习惯c++指针语法。毕竟这是一种不同的语言。

是的,有一个方法。不要将类与它的内存管理策略相结合。这是一种非常糟糕的做法。给你的用户你的CMesh类,让他们用它做他们想做的事情。类本身不应该关心它的实例被管理的方式。

应该通过复合模式将shared_ptr封装在另一个类中。例如:

class MMesh {
private:
    std::shared_ptr<glDetail::CMesh> mesh;
public:
    MMesh(const char *fileName) {
        mesh = std::shared_ptr<glDetail::CMesh>(new glDetail::CMesh(fileName));
    }
    glDetail::CMesh * operator -> () const {
        return mesh.get();
    }
};

///main.cpp
int main(int argc, char** args){
     MMesh mesh("someFileName");
     mesh->Render();
}

我只写了一个构造函数和操作符->,我很确定你将需要其他构造函数和一些其他方法来正确使用shared_ptr,但是你忘了说你想如何使用它或者为什么需要它。