首页 > 其他分享 >PImpl:Pointer to Implementation

PImpl:Pointer to Implementation

时间:2024-04-26 09:12:33浏览次数:22  
标签:default widget const Implementation draw PImpl implementation Pimpl Pointer

Pimpl(Pointer to implementation)是一种C++编程技术,用于将类的实现细节与其接口分离。通常情况下,类的实现细节会暴露在类的头文件中,这会增加代码的复杂性并使得类的修改和维护变得困难。使用Pimpl技术,可以在类的头文件中只暴露必要的接口,而将具体实现细节放在单独的实现文件中,通过指向这个实现的指针来访问。

Pimpl技术可以带来以下好处:

  1. 将类的实现细节隐藏起来,使得类的接口更加简洁和清晰。
  2. 降低了代码的耦合性,修改类的实现不会影响用户代码。
  3. 可以减小编译依赖关系,减少编译时间。
  4. 通过使用智能指针(如std::unique_ptr)可以避免内存泄漏和删除对象时的不一致性问题。

使用Pimpl技术也有一些缺点,如额外的内存开销和性能损耗等。因此,在实际应用中需要根据情况来权衡是否使用这种技术。

在实际项目中,当某个类作为接口需要导出时,可以考虑使用Pimpl,这样可以只暴露必要的接口,隐藏实现细节,降低耦合。

以下是Pimpl的例子:

// ----------------------
// interface (widget.hpp)
#include <experimental/propagate_const>
#include <iostream>
#include <memory>
 
class widget
{
    class impl;
    std::experimental::propagate_const<std::unique_ptr<impl>> pImpl;
public:
    void draw() const; // public API that will be forwarded to the implementation
    void draw();
    bool shown() const { return true; } // public API that implementation has to call
 
    widget(); // even the default ctor needs to be defined in the implementation file
              // Note: calling draw() on default constructed object is UB
    explicit widget(int);
    ~widget(); // defined in the implementation file, where impl is a complete type
    widget(widget&&); // defined in the implementation file
                      // Note: calling draw() on moved-from object is UB
    widget(const widget&) = delete;
    widget& operator=(widget&&); // defined in the implementation file
    widget& operator=(const widget&) = delete;
};
 
// ---------------------------
// implementation (widget.cpp)
// #include "widget.hpp"
 
class widget::impl
{
    int n; // private data
public:
    void draw(const widget& w) const
    {
        if (w.shown()) // this call to public member function requires the back-reference 
            std::cout << "drawing a const widget " << n << '\n';
    }
 
    void draw(const widget& w)
    {
        if (w.shown())
            std::cout << "drawing a non-const widget " << n << '\n';
    }
 
    impl(int n) : n(n) {}
};
 
void widget::draw() const { pImpl->draw(*this); }
void widget::draw() { pImpl->draw(*this); }
widget::widget() = default;
widget::widget(int n) : pImpl{std::make_unique<impl>(n)} {}
widget::widget(widget&&) = default;
widget::~widget() = default;
widget& widget::operator=(widget&&) = default;
 
// ---------------
// user (main.cpp)
// #include "widget.hpp"
 
int main()
{
    widget w(7);
    const widget w2(8);
    w.draw();
    w2.draw();
}

 

参考:

【1】https://blog.csdn.net/qq_21438461/article/details/132900415

【2】https://en.cppreference.com/w/cpp/language/pimpl

 

标签:default,widget,const,Implementation,draw,PImpl,implementation,Pimpl,Pointer
From: https://www.cnblogs.com/kuaixue/p/18159184

相关文章

  • Pointer-like classes像指针又像函数
    Pointer-likeclasses像指针又像函数智能指针概念:一个类做出来像类又像指针示例代码:#pragmaonce#ifndef__SHAREPOINTER__#define__SHAREPOINTER__​template<classT>classshared_ptr{public:shared_ptr(T*p):px(p){}T&operator*()const{return*px;}......
  • Class with pointer member(s) -> 带指针的类
    Classwithpointermember(s)->带指针的类String字符串为讲解对象设计一个Class先设计头文件示例代码:#pragmaonce​//防卫式声明#ifndef__STRING__#define__STRING__​#include<string.h>​//头文件定义classString{public://设计构造函数->这里只是定义了......
  • Effects of Anti Pimples
    看这篇题解这种转化应该比较容易吧,考虑贡献就好了。。转化之后将\(a\)升序排序应该也是比较自然的讲一下为什么这种转化是正确的:我们考虑一一映射。对原来的一个子序列,我们按照其最大值为第一关键字,下标为第二关键字进行排序,显然会唯一映射到某一序列;对排序之后的序列,我们不妨假......
  • [code notes] the implementation of alter table
    OverviewInthisarticle,Iwillinspectthepostgresqlcodetofindouttheimplementationofaltertablecommand,specifically,theaddcolumnsubcommandofthealtertablecommand.Thecodeforthisarticleisfrompostgresqlcommithash21e3a8bc3544a1......
  • QT 智能指针 QPointer QScopedPointer QSharedPointer QWeakPointer QSharedDataPoint
    QPointerQPointer是一种受保护的指针,当其引用的对象被销毁时,它会被自动清除(但是,销毁引用对象还是必须手动delete)。QPointer所指向的对象必须是QObject或其派生类对象。当多个指针指向同一个Object对象时,引用的对象可能被释放掉,这时使用QPointer就可以安全的测试引用对象是......
  • C++ pointer
    int*pInt=newint;*pInt=5;cout<<"---------------"<<endl;cout<<"&(*pInt)-->"<<&(*pInt)<<endl;cout<<"pInt-->"<<pInt<<endl......
  • PIMPL的优点和注意事项
    优点降低耦合度:使用PIMPL可以减少头文件的依赖,降低编译时的耦合度。隐藏实现细节:实现细节对使用者是不可见的,有利于封装。编译依赖减少:当实现改变时,不需要重新编译依赖于接口的代码,只需重新编译实现代码即可。注意事项:运行时性能:每次通过指针访问实现类可能会有轻微的性能......
  • PIMPL
    PIMPL(PointertoImplementation)本质上也属于设计模式的一种,PIMPL也称为OpaquePointer(不透明的指针)。主要目的是将一个类的实现细节(private/protected方法、成员)和其对外的公共接口分离出来,使得实现细节可以在不影响客户端代码的情况下进行更改。这样做的好处主要有以下......
  • Go 100 mistakes - #32: Ignoring the impact of using pointer elements in range lo
    Thissectionlooksataspecificmistakewhenusingarangeloopwithpointerelements.Ifwe’renotcautiousenough,itcanleadustoanissuewherewereferencethe wrongelements.Let’sexaminethisproblemandhowtofixit.Beforewebegin,let’scla......
  • BEVDet的进阶BEVPoolv2:A Cutting-edge Implementation of BEVDet Toward Deployment
    论文地址:https://arxiv.org/pdf/2211.17111.pdf​arxiv.org/pdf/2211.17111.pdf代码地址:GitHub-HuangJunJie2017/BEVDet:OfficialcodebaseoftheBEVDetseries.​github.com/HuangJunJie2017/BEVDet/tree/dev2.0整体思想:作者从工程优化的角度考虑优化BEVDet,提出了B......