渲染(); },c++,c++11,C++,C++11" /> 渲染(); },c++,c++11,C++,C++11" />

隐藏共享的ptr实现 我有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(); } 名称空间详细信息 { 类CMesh { 公众: CMesh(常量字符*文件名); ///还有一些功能。。。 CMesh和运算符=(常量CMesh和其他)=删除; CMesh(const CMesh&other)=delete;///请注意,赋值运算符已禁用! //这就是为什么我需要使用共享的PTR! 私人: ///一些成员变量。。。 }; } typedef共享_ptr网格; 共享\u ptr CreateMesh(常量字符*文件名){ 制作 } ///main.cpp int main(int argc,char**args){ 网格网格=CreateMesh(“someFileName”); 网格->渲染(); }

隐藏共享的ptr实现 我有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(); } 名称空间详细信息 { 类CMesh { 公众: CMesh(常量字符*文件名); ///还有一些功能。。。 CMesh和运算符=(常量CMesh和其他)=删除; CMesh(const CMesh&other)=delete;///请注意,赋值运算符已禁用! //这就是为什么我需要使用共享的PTR! 私人: ///一些成员变量。。。 }; } typedef共享_ptr网格; 共享\u ptr CreateMesh(常量字符*文件名){ 制作 } ///main.cpp int main(int argc,char**args){ 网格网格=CreateMesh(“someFileName”); 网格->渲染(); },c++,c++11,C++,C++11,有没有一种方法可以隐藏这个实现,而不是调用CreateXXX调用一个合适的构造函数?(同时调用->而不是.会让人困惑…)比如Mesh=Mesh(“someFileName”) 是的,有办法。不要使类与它的内存管理策略相协调。这是一种非常糟糕的做法。给你的用户你的CMesh类,让他们做他们想做的事情。类不应该关心其实例的管理方式。您应该通过组合模式将共享的ptr封装在另一个类中。例如: class MMesh { private: std::shared_ptr<glDetail::

有没有一种方法可以隐藏这个实现,而不是调用CreateXXX调用一个合适的构造函数?(同时调用->而不是.会让人困惑…)比如Mesh=Mesh(“someFileName”)

是的,有办法。不要使类与它的内存管理策略相协调。这是一种非常糟糕的做法。给你的用户你的CMesh类,让他们做他们想做的事情。类不应该关心其实例的管理方式。

您应该通过组合模式将共享的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();

}
MMesh类{
私人:
std::共享的ptr网格;
公众:
MMesh(常量字符*文件名){
mesh=std::shared_ptr(新的glDetail::CMesh(文件名));
}
glDetail::CMesh*运算符->()常量{
返回mesh.get();
}
};
///main.cpp
int main(int argc,char**args){
MMesh网格(“someFileName”);
网格->渲染();
}
我只编写了一个构造函数和操作符
->
,我很确定您需要其他构造函数和一些其他方法来正确使用
共享\u ptr
,但您忘记了说明您希望如何使用它或为什么需要它。

问题是,对于自定义类型,只能重载
->
,不是
。重载
->
使智能指针类能够向其所属对象的成员函数提供简单的委托,即只需编写
mesh->Render()
而不是
(*mesh).Render()

要获得一些语法上的支持,您唯一能做的就是将您的
typedef
升级到一个实际的包装类,该包装类封装了
共享的\u 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();
}

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

完全不清楚为什么需要共享指针。你的意思是实现一个单件吗?不是;Mesh是一个基于opengl的类:它的赋值操作符是禁用的,所以如果我使用CMesh,我必须将它作为指针传递,几乎在任何地方……我不能给我的用户这个CMesh类,因为他们必须在任何地方通过指针传递东西,这甚至是最糟糕的……我对此表示怀疑。共享ptr的合法使用非常少(我所看到的所有使用中99%是不合理的),而传递共享ptr的合法使用则更少。传递SypDypPTR实际上是一件非常糟糕的事情,因为它是一个真正的性能杀手。2)我困惑的是,对于用户来说:他认为他创建的对象是一个对象,但随后调用它就像一个指针。@ CODR32:在C++中,原始类型也变成了“对象”,所以指针是一个对象。您可能是指自定义类型的对象。但这不是重点。关键是对于像
CreateMesh
这样的函数,我希望返回一个指针。不是因为“创建”部分,而是因为网格听起来像是无法自由复制或分配的东西。更难的问题是哪种指针:原始的、共享的还是唯一的。好的,谢谢。我开始了关于这个主题的另一个问题(主题不同);你可以帮忙,也许:)糟糕的设计。糟糕的设计!如果必须在类中包含shared_ptr(根据经验法则,不要!),那么还必须包含分配器。否则,您将对您的用户造成极大的伤害。@SergeyA:这句话太宽泛了,因为我们不知道这个类将如何使用;特别是,我们不知道这是库代码还是应用程序代码。
 auto mesh = Mesh { "someFileName" };