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;
}
posted @ 2022-04-06 22:58  Fancele  阅读(137)  评论(0)    收藏  举报