C++ Pimpl习惯用法

Pimpl习惯用法

Pimpl(pointer to implementation):指向实现的指针。

把某类的数据成员用一个指向某实现类(或结构体)的指针替代,然后把原来在主类的数据成员放到实现类中,并通过指针间接访问这些数据成员。例如:

class Gadget{};//位于头文件Gadget.h中
class Widget {//位于widget.h头文件中
public:
	Widget();
private:
	string name;
	vector<double> data;
	Gadget g1, g2, g3;
};

由于要包含#include #include #include"gadget”头文件,导致编译速度变慢,而且假设gadget.h内容被改变,widget.h又要重新编译。此时就需要使用Pimpl习惯用法:
widget.h

class Widget {
public:
	Widget();
	~Widget();//析构函数必须
private:
	struct Impl;//声明实现结构体
	Impl* pImpl;//指向该结构体的指针
};

其中Widget::Impl就是一个非完整类型:已声明但未定义。
Pimpl习惯用法:
1、声明一个指针类型的数据成员,指向一个非完整类型;
2、动态分配和回收持有从前在原始类的数据成员的对象,而代码在实现文件中。
实现文件widget.cpp:

#include"widget.h"
#include"gadget.h"
#include<string>
#include<vector>
using namespace std;

struct Widget::Impl {
	string name;
	vector<double> data;
	Gadget g1, g2, g3;
};

Widget::Widget() :pImpl(new Ipml) {}
Widget::~Widget() { delete pImpl; }

考虑到C++11的智能指针,提出改进版本:
widget.h

class Widget {
public:
	Widget();
	//~Widget();
private:
	struct Impl;//声明实现结构体
	//Impl* pImpl;//指向该结构体的指针
	shared_ptr<Impl> pImpl;
};

实现文件widget.cpp:

#include"widget.h"
#include"gadget.h"
#include<string>
#include<vector>
using namespace std;

struct Widget::Impl {
	string name;
	vector<double> data;
	Gadget g1, g2, g3;
};

Widget::Widget():pImpl(make_shared<Impl>()){}
//Widget::Widget() :pImpl(new Ipml) {}
//Widget::~Widget() { delete pImpl; }

避免了裸指针的使用,析构函数也不用书写,自动析构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dailingGuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值