C++程序设计的技巧-Pimple的使用

1.Pimpl概念

 在进行项目开发中可能遇到的问题,程序编译耗时很长,每一次简单修改接口之后项目都会被完全重新编译,浪费了很多时间。这个机制是Private Implementation的缩写,顾明思议,将实现私有化,力图使得头文件对改变不透明.它的优点很多,诸如降低编译依赖、提高重编译速度之类的工具性优势、同时保持接口的稳定性。

 

2.Pimpl机制

 Pimpl惯用法的基本思想是使用一个结构将原有接口class的私有数据成员和一些不希望被外界调用的对数据成员操作的过程封装起来,此时class的私用成员的结构看起来是:

 private:

     struct Member;

     Member* data_member;

将这个Member的结构实现放在cpp文件中,类的私有成员中只能看到Member结构的前向声明以及一个该结构的指针。

这样就将一些我们不期望被用户调用的过程封装起来,可以防止资源泄露。同时类与数据成员之间的耦合最低,类看起来总是一个样子,包含该类声明的文件也不会因为类实现的改变而重新编译,节约了编译时间.

 

原有类:

 1 class Person{
 2 public:
 3    Person(void);
 4    ~Person();
 5 
 6 private:
 7    string name;
 8    size_t age;
 9    string from;
10    string work;
11 };

Pimpl惯用法修改后:

1 class Person{
2 public:
3     Person(void);
4     ~Person();
5 private:
6    struct Member;
7    Member* data_member;
8 }

Member相关实现在另一个cpp文件中,很明显,修改后Person类与数据成员的耦合度大大降低,用户对其他细节也变得不可见了。

 

例子:

   在Pimpl机制中,我们使用前置声明一个impl类,并将这个类的一个指针实例放入主类中,如下:

//MyClass.h
class MyClassImpl;  //forward declaration
class MyClass{
public:
    MyClass();
    ~MyClass();
    int foo();
    
private:
    MyClassImpl * m_pImpl;
};

现在,除非我们修改MyClass的公有接口,否则这个头文件是不会被修改了。然后,我们用这个Impl类的实现来完成主类的细节实现,在主类的构造函数中,我们完成了实现类指针的实例化:

 1 //MyClass.cpp
 2 class MyClassImpl{
 3 public:
 4     int foo(){return bar();}
 5     
 6     int bar(){return var++;}
 7     int var;
 8 };
 9 
10 MyClass::MyClass:m_Impl(new MyClassImpl){}
11 MyClass::~MyClass(){
12     try{
13         delete m_pImpl;
14     }
15     catch(...){}
16 }
17 
18 int MyClass::foo(){return m_pImpl->foo();}

Pimpl机制其实是桥接模式的一种变类。我们可以对实现类随意的进行增删和修改,而不会导致包含MyClass的源代码重新编译。当然,这样做的时间开销和空间开销也是有的。

 

转载于:https://www.cnblogs.com/sixue/p/4293418.html

icoFoam 求解器名称 |-createFields.H 场变量的声明和初始化 ————————————————————————————————————————————— Info<< "Reading transportProperties\n" << endl; //屏幕提示读入参数控制文件,等价于 C++中std::cout //声明属性字典类对象,该对象由 constant 文件夹下的“transportProperties”初始化创建。 IOdictionary transportProperties ( IOobject //其实IOobject,顾名思义就是输入输出对象,它完成的是一个桥梁的作用,即连接要构造的类及硬盘中的相应文件。这可以通过其成员函数objectStream()了解到,当完成了“搭桥”之后,便可通过这一成员函数返回硬盘文件对应的输入流,从而从输入流中读入将要构造的类的相关信息// ( "transportProperties", // 文件名称 runTime.constant(), // 文件位置,case/constant mesh, // 网格对象 IOobject::MUST_READ_IF_MODIFIED, //如果更改,必须读入 IOobject::NO_WRITE // 不对该文件进行写操作 ) ); //字典查询黏性,以便初始化带有单位的标量 dimensionedScalar nu ( transportProperties.lookup("nu") ); //屏幕提示创建压力场 Info<< "Reading field p\n" << endl; //创建压力场 volScalarField p //声明一个带单位的标量场,网格中心存储变量。 ( IOobject // IOobject主要从事输入输出控制 ( "p", // 压力场初始文件名称 runTime.timeName(), // 文件位置,由case中的system/controlDict中的startTime控制 //
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值