pimpl设计模式和单例模式的自动回收
类型转换
- 由其他类型向自定义类类型转换(通过自定义类类型的构造函数完成)
如果不想要隐式转换的话,可以在前面加上explicit关键字。
- 由自定义类型向其他类型转换(类型转换函数)
#include <iostream>
#include <limits>
using std::cout;
using std::endl;
class Point;
class Complex
{
public:
//explicit
Complex(const Point & rhs);
Complex(double dreal, double dimage = 0)
: _dreal(dreal)
, _dimage(dimage)
{
cout << "Complex(double, double)" << endl;
}
//类型转换函数
operator double()
{
cout << "operator double()" << endl;
return _dreal ;
}
operator Point();
void print() const
{
cout << _dreal << " + " << _dimage << "i" << endl;
}
//友元函数
friend std::ostream & operator<<(std::ostream & os, const Complex & rhs);
friend std::istream & operator>>(std::istream & is, Complex & rhs);
private:
friend Complex operator+(const Complex & lhs, const Complex & rhs);
double _dreal; //实部
double _dimage; //虚部 i^2 == -1
};
//友元函数形式重载, 友元函数本身是一个普通函数
//参数形式都为const的, 因为执行之后参数是保持不变的
Complex operator+(const Complex & lhs, const Complex & rhs)
{
return Complex(lhs._dreal + rhs._dreal,
lhs._dimage+ rhs._dimage);
}
std::ostream & operator<<(std::ostream & os, const Complex & rhs)
{
os << rhs._dreal << " + " << rhs._dimage << "i" << endl;
return os;
}
void readDouble(std::istream & is, double & number)
{
while(is >> number, !is.eof())
{
if(is.bad()) {
cout << "istream has broken!" << endl;
return;
} else if(is.fail()) {
is.clear();
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "pls input a valid double number:" << endl;
} else {
break;
}
}
}
std::istream & operator>>(std::istream & is, Complex & rhs)
{
readDouble(is, rhs._dreal);
readDouble(is, rhs._dimage);
return is;
}
class Point
{
friend class Complex;
public:
Point(int ix = 0, int iy = 0)
: _ix(ix)
, _iy(iy)
{}
friend std::ostream & operator<<(std::ostream &os, const Point & rhs);
private:
int _ix;
int _iy;
};
std::ostream & operator<<(std::ostream &os, const Point & rhs)
{
os << "(" << rhs._ix
<< "," << rhs._iy
<< ")";
return os;
}
Complex::Complex(const Point & rhs)
: _dreal(rhs._ix)
, _dimage(rhs._iy)
{
cout << "Complex(const Point&)" << endl;
}
//类型转换函数
Complex::operator Point()
{
cout << "operator Point()" << endl;
return Point(_dreal, _dimage);
}
void test0()
{
Complex c1(1, 2), c2(3, 4);
cout << "c1:" << c1 << endl;
//由其他类型向自定义类型转换
//由构造函数来完成
Complex c3 = 1.1;//隐式转换
cout << "c3:" << c3 << endl;
Point pt(11, 12);
cout << "pt:" << pt << endl;
//将一个Point类型的对象转换为Complex的对象
Complex c4 = pt;//已经违反常规思维, 尽量少用或者不用
cout << "c4:" << c4 << endl;
}
void test1()
{
Complex c1(11.11, 22);
int x = c1;//将自定类类型向其他类型(int)转换
cout << "x:" << x << endl;
Point pt(2, 3);
pt = c1;//将自定类类型向其他类型(Point)转换
cout << "pt:" << pt << endl;
}
int main(void)
{
/* test0(); */
test1();
return 0;
}
pimpl设计模式
#include<bits/stdc++.h>
using namespace std;
class Line
{
public:
Line(int,int,int,int);
~Line();
void printLine() const;
class LineImpl;//内部类
private:
LineImpl *_pimpl;
};
class Line::LineImpl//全局类
{
private:
//内部类
class Point{
public:
Point(int ix=0,int iy=0)
:_ix(ix)
,_iy(iy)
{}
void print()const;
private:
int _ix;
int _iy;
};
public:
LineImpl(int x1,int y1,int x2,int y2)
:_pt1(x1,y1)
,_pt2(x2,y2)
{
cout<<"LineImpl(int,int,int,int)"<<endl;
}
void printLine() const{
_pt1.print();
cout<<"--->";
_pt2.print();
cout<<endl;
}
private:
Point _pt1;
Point _pt2;
};
void Line::LineImpl::Point::print()const{
cout<<"("<<_ix<<","<<_iy<<")";
}
Line::Line(int x1,int y1,int x2,int y2)
:_pimpl(new LineImpl(x1,x2,y1,y2)){
cout<<"Line(int,int,int,int)"<<endl;
}
Line::~Line(){
if(_pimpl){
delete _pimpl;
_pimpl=nullptr;
}
cout<<"~Line()"<<endl;
}
void Line::printLine()const {
_pimpl->printLine();
}
void test0(){
Line line(1,2,3,4);
line.printLine();
}
int main(){
test0();
return 0;
}
该设计模式的好处:
1、实现信息隐藏
2、在接口是固定的情况下,如果要升级库,就能以最小的代价完成库的升级(只需用新的库代替原来的库)
单例模式的自动回收(释放)
-
单例模式一般情况下是在程序退出时进行回收,她的生命周期是整个程序都正常执行都存在的。
-
如果单例对象不进行回收,那么我们就要查找程序中出现了内存泄漏的地方时,就会对我们造成影响,因此单例对象必须要回收。
1、嵌套类+静态对象
#include<bits/stdc++.h>
using namespace std;
class Singleton{
public:
class AutoRelease{
public:
AutoRelease(){
cout << "AutoRelease()" <<endl;
}
~AutoRelease(){
if(_pInstance != nullptr){
delete _pInstance;
_pInstance = nullptr;
}
cout << "~AutoRelease()" <<endl;
}
};
static Singleton *getInstance(){
if(_pInstance == nullptr){
_pInstance = new Singleton();
}
return _pInstance;
}
private:
Singleton(){
cout << "Singleton()" <<endl;
}
~Singleton(){
cout << "~Singleton()" << endl;
}
int _data;
static AutoRelease _ar;
static Singleton *_pInstance;
};
Singleton * Singleton::_pInstance = nullptr;
Singleton::AutoRelease Singleton::_ar;
void test1(){
Singleton * ps1 = Singleton::getInstance();
Singleton * ps2 = Singleton::getInstance();
printf("ps1: %p\n",ps1);
printf("ps2: %p\n",ps2);
}
int main(){
test1();
return 0;
}
2、atexit+静态函数(饱汉模式)
#include<bits/stdc++.h>
using namespace std;
class Singleton{
public:
static Singleton *getInstance(){
if(_pInstance == nullptr){
_pInstance = new Singleton();
atexit(destory);//atexit+静态函数
}
return _pInstance;
}
static void destory(){//静态对象
if(_pInstance){
delete _pInstance;
_pInstance = nullptr;
}
cout << "destory()" <<endl;
}
private:
Singleton(){
cout << "Singleton()" <<endl;
}
~Singleton(){
cout << "~Singleton()" << endl;
}
int _data;
static Singleton *_pInstance;
};
Singleton * Singleton::_pInstance = nullptr;
void test1(){
Singleton * ps1 = Singleton::getInstance();
Singleton * ps2 = Singleton::getInstance();
printf("ps1: %p\n",ps1);
printf("ps2: %p\n",ps2);
}
int main(){
test1();
return 0;
}
3、pthread形式
#include<bits/stdc++.h>
using namespace std;
class Singleton{
public:
static Singleton *getInstance()
{
pthread_once(&_once, init);
return _pInstance;
}
static void init()
{
atexit(destroy);
_pInstance = new Singleton();
}
static void destroy()
{
if (_pInstance) {
delete _pInstance;
_pInstance = nullptr;
}
}
private:
Singleton()
: _data(111)
{
cout << "Singleton()" << endl;
}
~Singleton() {
cout << "~Singleton()" << endl;
}
private:
int _data;
static pthread_once_t _once;
static Singleton * _pInstance;
};
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;
Singleton *Singleton::_pInstance = nullptr;
void test0() {
Singleton *ps1 = Singleton::getInstance();
Singleton *ps2 = Singleton::getInstance();
cout << "ps1: " << ps1 << endl;
cout << "ps2: " << ps2 << endl;
}
int main(void) {
test0();
return 0;
}
4、
include <bits/stdc++.h>
using namespace std;
class Singleton{
public:
static Singleton &getInstance()
{
static Singleton s;
return s;
}
private:
Singleton()
: _data(111)
{
cout << "Singleton()" << endl;
}
~Singleton() {
cout << "~Singleton()" << endl;
}
private:
int _data;
};
void test0() {
Singleton &ps1 = Singleton::getInstance();
Singleton &ps2 = Singleton::getInstance();
cout << "ps1: " << &ps1 << endl;
cout << "ps2: " << &ps2 << endl;
}
int main(void) {
test0();
return 0;
}

浙公网安备 33010602011771号