关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭8年前。Improvethisquestion我当前的项目涉及编写C++API,我决定使用PIMPL惯用法。我是否应该在我的项目中到处使用PIMPL习语,例如我需要创建一个继承自std::exception的自定义类,我应该在设计此类时考虑PIMPL习语还是可以我只是作为一个公共(public)实现来编写?仅仅因为我使用的是PIMPL习语就认为我创建的每个类都应该围绕它来设计,这感觉是错误的。PIMPL是否应该不被使用?
据我了解,pimpl习惯用法的主要好处是将数据成员隐藏在实现文件而不是header中。但是,需要在header中完整定义模板,以便编译器按需实例化它们。在这种情况下,对模板类使用pimpl习惯用法有什么好处吗? 最佳答案 虽然在模板类中使用pimpl习惯用法并没有真正隐藏任何内容,但它确实允许您轻松编写非抛出交换(尽管使用C++11移动语义这不是一个问题)。 关于c++-使用模板化类的pimpl习语有什么优势吗?,我们在StackOverflow上找到一个类似的问题:
我正在使用pimpl惯用法实现几个类,并且遇到了一些设计问题。首先,我一直看到pimpl是这样做的classObject{public:Visible();~Visible();..etc..private:classObjectImpl*_pimpl;};我有几个使用这种方法的类,我的问题是其中几个类需要访问彼此的实现细节,但_pimpl指针是私有(private)的。谁能看到将_pimpl公开的缺点。显然,如果它是公开的,那么有人可能会不小心(或故意)重新分配它。(我忽略了一个事实,即“私有(private)”可以#defined为“公共(public)”并授予访问权限。如果您这样
传统的PImplIdiom是这样的:#includestructBlah{//publicinterfacedeclarationsprivate:structImpl;std::unique_ptrimpl;};//insourceimplementationfile:structBlah::Impl{//privatedata};//publicinterfacedefinitions然而,forfun,Itried改为使用具有私有(private)继承的组合:[测试.h]#include#includetemplatestructPImplMagic{PImplMagic(){s
背景我一直在学习如何使用HerbSutter在本页描述的更新的c++11方法来实现pimpl习语:https://herbsutter.com/gotw/_100/我试图通过向私有(private)实现添加成员变量来修改此示例,特别是std::string(尽管char*具有相同的问题)。问题由于使用了staticconst非整数类型,这似乎是不可能的。只能对整数类型进行类内初始化,但由于它是静态的,因此也不能在构造函数中进行初始化。解决这个问题的方法是在头文件中声明私有(private)变量,并在实现中对其进行初始化,如下所示:C++staticconstantstring(clas
我正在阅读ScottMeyers的EffectiveModernC++,他正在讨论pimpl习语的使用,并使用unique_ptr指向实现类,但存在特殊成员函数的问题(例如析构函数)要求类型完整。这是因为unique_ptr的默认删除器在使用deletep之前静态断言要删除的类型是否完整。因此类的任何特殊成员函数都必须在实现文件中定义(而不是由编译器生成),在实现类定义之后。在章节的最后,他提到如果使用的智能指针是shared_ptr,就不需要在实现文件中定义特殊的成员函数,这源于它支持自定义的方式删除器。引用:Thedifferenceinbehaviorbetweenstd::un
所以我一直在思考PIMPL和堆栈分配。我一直在编写一个库,并决定使用PIMPL来隐藏该类的私有(private)成员。这意味着我将有一个这样声明的类classFoo{private:classHandle;std::tr1::shared_ptrhandle;public:Foo();};这很简单。但是然后在构造函数中你这样做Foo::Foo():handle(newHandle()){}因此,当使用我的库的人在堆栈上创建Foo时,他们实际上是在进行堆分配。这是您在使用PIMPL时必须忍受的权衡吗?我想在构造函数旁边发布带有警告的文档:“警告:这会导致堆分配”或类似的内容。我的另一个想
假设我有一个带有私有(private)成员的类,这是类的客户不关心的实现细节。这个类是一个值类型,我们希望它是可复制的,例如#include//someheaderthatpullsinmanyotherfilesclassMyClass{public:MyClass(){}...private:boost::bimaptable;};现在,MyClass的每个客户端都被迫引入许多它并不真正需要的boostheader,从而增加了构建时间。但是,该类至少是可复制的。如果我们引入编译器防火墙(Pimpl习惯用法),那么我们可以将#include依赖项移动到cpp文件,但由于5规则,现在我
我正在尝试使用pimpl模式并在匿名命名空间中定义实现类。这在C++中可能吗?我失败的尝试如下所述。是否可以在不将实现移动到具有名称(或全局名称)的namespace的情况下解决此问题?classMyCalculatorImplementation;classMyCalculator{public:MyCalculator();intCalculateStuff(int);private:MyCalculatorImplementation*pimpl;};namespace//Ifiomitthenamespace,everythingisOK{classMyCalculatorIm
pimpl习语中使用的实现类有任何私有(private)成员吗?我真正能想到的唯一原因是保护自己免受自己的伤害——即私有(private)成员用于在类和用户之间执行某种契约,在这种情况下,类和用户关系密切,所以它似乎没有必要。 最佳答案 我认为人们将Pimpl惯用法与Adapter/Bridge/Strategy模式混淆了。习语是特定于一种语言的。模式可以应用于多种语言。Pimpl惯用法旨在解决C++中的以下问题:类的私有(private)成员在类声明中可见,这会向类的用户添加不必要的#include依赖项。此习语也称为编译器防火墙