私有实现封装方法
1.实现一个CSocketClient的网络通讯类
SocketClient.h
class CSocketClient
{
public:
CSocketClient();
~CSocketClient();
public:
bool Init();
private:
void fun1();
private:
//这里暴露了太多与实现细节相关的成员对象
SOCKET m_hSocket;
short m_nPort;
char m_szServer[64];
long m_nLastDataTime;
long m_nHeartbeatInterval;
}
SocketClient.c
#include "SocketClient.h"
CSocketClient::CSocketClient()
{
}
CSocketClient::~CSocketClient()
{
}
bool CSocketClient::Init()
{
return false;
}
void CSocketClient::fun1()
{
}
将SocketClient.h提供给客户太过危险,考虑将私有对象和私有方法封装到impl中
2.封装私有对象和方法细节
SocketClient.h
class Impl;
class CSocketClient
{
public:
CSocketClient();
~CSocketClient();
public:
bool Init();
private:
Impl *m_Impl;
}
SocketClient.c
#include "SocketClient.h"
class Impl
{
public:
Impl()
{
//@todo:
}
~Impl()
{
//@todo:
}
public:
void fun1();
public:
SOCKET m_hSocket;
short m_nPort;
char m_szServer[64];
long m_nLastDataTime;
long m_nHeartbeatInterval;
};
CSocketClient::CSocketClient()
{
m_Impl = new Impl();
}
CSocketClient::~CSocketClient()
{
delete m_Impl;
}
bool CSocketClient::Init()
{
return false;
}
void CSocketClient::fun1()
{
}
隐藏原来CSocketClient的私有方法和私有变量封装到Impl类中,但Impl是CSocketClient的辅助类,没有独立存在的必要,所以将Impl类定义成CSocketClient类的内部类
3.将Impl封装为CSocketClient内部类
SocketClient.h
class CSocketClient
{
public:
CSocketClient();
~CSocketClient();
//省略重复代码
private:
class Impl;
Impl *m_Impl;
}
SocketClient.c
#include "SocketClient.h"
class CSocketClient:: Impl
{
public:
void LoadConfig()
{
}
void fun1();
public:
SOCKET m_hSocket;
short m_nPort;
char m_szServer[64];
long m_nLastDataTime;
long m_nHeartbeatInterval;
};
CSocketClient::CSocketClient()
{
m_Impl = new Impl();
}
CSocketClient::~CSocketClient()
{
delete m_Impl;
}
4.使用智能指针管理Impl对象
已经使用智能指针管理m_pImpl指向堆内存,所以在析构函数中不需要显示地释放堆内存。
提供给客户SocketClient.h,即使更改CSocketClient的私有方法或增加私有变量也不影响外部接口实现
SocketClient.h
class CSocketClient
{
public:
CSocketClient();
~CSocketClient();
public:
bool Init();
private:
class Impl;
std::unique_ptr<Impl> m_pImpl; //智能指针
};
SocketClient.c
#include "SocketClient.h"
#include <memory>
class CSocketClient:: Impl
{
public:
void LoadConfig();
void fun1();
public:
SOCKET m_hSocket;
short m_nPort;
char m_szServer[64];
long m_nLastDataTime;
long m_nHeartbeatInterval;
};
CSocketClient::CSocketClient(): m_pImpl(std::make_unique<Impl>())
{
std::cout << "构造函数" << endl;
}
CSocketClient::~CSocketClient()
{
std::cout << "析构函数" << endl;
}
bool CSocketClient::Init()
{
return false;
}
void CSocketClient::Impl::LoadConfig()
{
}
void CSocketClient::Impl::fun1()
{
}