C++:线上课程2_22(shared_ptr指针)


一、工厂模式

1.静态函数

在进入主函数之前对静态成员进行初始化

class Object
{
private:
	int value;
	static int num;
	static Object objx;
public:
	Object(int x=0) :value(x) {}
};
int Object::num = 10;
Object Object::objx(20);//在进入主函数之前对静态成员进行初始化


int main()
{

}

2.工厂模式

#include<iostream>
#include<atomic>
#include<string>
#include<map>
#include<memory>
using namespace std;

//工厂方式
class Shape //接口
{
public:
	Shape()
	{
		cout << "Shape" << endl;
	}
	virtual ~Shape()
	{
		cout << "~Shape" << endl;

	}	
	//虚函数
	virtual void draw() = 0;
	virtual void erase() = 0;
};

class Circle : public Shape
{
public:
	Circle()
	{
		cout << "Circle" << endl;
	}
	virtual ~Circle()
	{
		cout << "~Circle" << endl;
	}
	//重写成员方法
	void draw()//绘图函数
	{
		cout << "circle::draw" << endl;
	}
	void erase()//删除圆函数
	{
		cout << "circle::erase" << endl;
	}
};

class Square : public Shape
{
public:
	Square()
	{
		cout << "Square" << endl;
	}
	virtual ~Square()
	{
		cout << "~Square" << endl;
	}
	void draw()
	{
		cout << "Square::draw" << endl;
	}
	void erase()
	{
		cout << "Square::erase" << endl;
	}
};

//形状工厂
class ShapeFactory
{
public:
	ShapeFactory()
	{
		cout << "ShapeFactory" << endl;
	}
	virtual ~ShapeFactory()
	{
		cout << "~ShapeFactory" << endl;
	}
	virtual Shape* create() = 0;
public:
	static std::map<string, ShapeFactory*> factories;//键值对
	static Shape* createShape(const string& id)
	{
		if (factories.find(id) != factories.end())
		{
			return factories[id]->create();
		}
		else
		{
			return nullptr;
		}
	}
};
std::map<string, ShapeFactory*> ShapeFactory::factories;

//圆的形状工厂
class CircleFactroy : public  ShapeFactory
{
public:
	CircleFactroy()
	{
		cout << "CircleFactroy" << endl;
	}
	~CircleFactroy()
	{
		cout << "~CircleFactroy" << endl;
	}
	virtual Shape* create()
	{
		return new Circle();
	}
};

//正方形工厂
class SquareFactroy : public  ShapeFactory
{
public:
	SquareFactroy()
	{
		cout << "SquareFactroy" << endl;
	}
	~SquareFactroy()
	{
		cout << "~SquareFactroy" << endl;
	}
	virtual Shape* create()
	{
		return new Square();
	}
};

class ShapeFactoryInitializer
{
	static ShapeFactoryInitializer si;
	ShapeFactoryInitializer()
	{
		//key value ShapeFactroy*                            
		ShapeFactory::factories["Circle"] = new CircleFactroy();
		ShapeFactory::factories["Square"] = new SquareFactroy();//添加矩形工厂
	}
};

ShapeFactoryInitializer ShapeFactoryInitializer::si;
// Client
int main()
{
	Shape* shape = ShapeFactory::createShape("Circle");

	shape->draw();
	shape->erase();

	shape = ShapeFactory::createShape("Square");

	shape->draw();
	shape->erase();


	return 0;
}

3.抽象工厂模式智能指针表达法

#include<iostream>
#include<atomic>
#include<string>
#include<map>
#include<memory>
using namespace std;

//工厂方式
class Shape //接口
{
public:
	Shape()
	{
		cout << "Shape" << endl;
	}
	virtual ~Shape()
	{
		cout << "~Shape" << endl;

	}	
	//虚函数
	virtual void draw() = 0;
	virtual void erase() = 0;
};

class Circle : public Shape
{
public:
	Circle()
	{
		cout << "Circle" << endl;
	}
	virtual ~Circle()
	{
		cout << "~Circle" << endl;
	}
	//重写成员方法
	void draw()//绘图函数
	{
		cout << "circle::draw" << endl;
	}
	void erase()//删除圆函数
	{
		cout << "circle::erase" << endl;
	}
};

class Square : public Shape
{
public:
	Square()
	{
		cout << "Square" << endl;
	}
	virtual ~Square()
	{
		cout << "~Square" << endl;
	}
	void draw()
	{
		cout << "Square::draw" << endl;
	}
	void erase()
	{
		cout << "Square::erase" << endl;
	}
};

//形状工厂
class ShapeFactory
{
public:
	ShapeFactory()
	{
		cout << "ShapeFactory" << endl;
	}
	virtual ~ShapeFactory()
	{
		cout << "~ShapeFactory" << endl;
	}
	virtual std::shared_ptr<Shape> create() = 0;
public:
	static std::map<string, std::shared_ptr<ShapeFactory>>factories;//键值对
	static std::shared_ptr<Shape> createShape(const string& id)
	{
		if (factories.find(id) != factories.end())
		{
			return factories[id]->create();
		}
		else
		{
			return nullptr;
		}
	}
};
std::map<string, std::shared_ptr<ShapeFactory>>ShapeFactory::factories;

//圆的形状工厂
class CircleFactroy : public  ShapeFactory
{
public:
	CircleFactroy()
	{
		cout << "CircleFactroy" << endl;
	}
	~CircleFactroy()
	{
		cout << "~CircleFactroy" << endl;
	}
	virtual std::shared_ptr<Shape> create()
	{
		return std::make_shared<Circle>();
	}
};

//正方形工厂
class SquareFactroy : public  ShapeFactory
{
public:
	SquareFactroy()
	{
		cout << "SquareFactroy" << endl;
	}
	~SquareFactroy()
	{
		cout << "~SquareFactroy" << endl;
	}
	virtual std::shared_ptr<Shape> create()
	{
		return std::make_shared<Square>();
	}
};

class ShapeFactoryInitializer
{
	static ShapeFactoryInitializer si;
	ShapeFactoryInitializer()
	{
		//key value ShapeFactroy*                            
		ShapeFactory::factories["Circle"] = std::make_shared <CircleFactroy>();
		ShapeFactory::factories["Square"] = std::make_shared <SquareFactroy>();
	}
};

ShapeFactoryInitializer ShapeFactoryInitializer::si;
// Client
int main()
{
	std::shared_ptr < Shape> shape = ShapeFactory::createShape("Circle");

	shape->draw();
	shape->erase();

	shape = ShapeFactory::createShape("Square");

	shape->draw();
	shape->erase();


	return 0;
}

4.工厂方法的隐藏

有时候,为了进一步简化客户端的使用,还可以对客户端隐藏工厂方法,此时,在工厂类中将直接调用产品类的业务方法,客户端无须调用工厂方法创建产品,直接通过工厂即可使用所创建的对象中的业务方法。
如果对客户端隐藏工厂方法,日志记录器的结构图将修改为图所示:
在这里插入图片描述

二、Boost提供的智能指针

1.分类

shared_ptr本指针中有一个引用指针记数器,表示类型T的对象是否已经不再使用。shared_ptr是 Boost中提供普通的智能指针,大多数地方都使用shared_ptr。
scoped_ptr当离开作用域能够自动释放的指针。因为它是不传递所有权的。事实上它明确禁止任何想要这样做的企图!这在你需要确保指针任何时候只有一个拥有者时的任何一种情境下都是非常重要的。
intrusive_ptr比shared_ptr更好的智能指针,但是需要类型提供自己的指针使用引用记数机制。
weak_ptr一个弱指针,帮助shared_ptr避免循环引用。
shared_array和shared_ptr类似,用来处理数组的。
scoped_array和shared_ptr类似,用来处理数组的。

2.初始化std方法

通常我们有两种方法去初始化一个std:shared_ptr:
1)通过它自己的构造函数
2)通过std::make_shared

shared_ptr是非侵入式的,即计数器的值并不存储在shared_ptr内,它其实是存储在其他地方——在堆上的。当一个shared_ptr由一块儿内存的原生指针创建的时候(原生内存:代指这个时候还没有其他shared_ptr指向这块内存),这个计数器也就随之产生。这个计数器结构的内存会一直存在—— —直到所有的shared_ptr和weak_ptr都被销毁的时候。这个时候就比较巧妙了,当所有shared_ptr都被销毁时,这块儿内存就已经被释放了,但是可能还有weak_ptr存在——也就是说计数器的销毁有可能发生在内存对象销毁后很久才发生。
在这里插入图片描述
当我们使用一个原生指针、一个unique_ptr或者通过一个空白shared_ptr来设置指向一块儿原生内存时,发生的内存分配和上边都很类似。就像大家都知道的,内存分配和回收基本上是C++中最慢的单次操作了。鉴于此,我们有一种办法来把这两种内存分配合二为一: std::make_shared。

std::make_shared可以同时为计数器和原生内存分配内存空间,并把二者的内存视作整体管理
在这里插入图片描述
使用make_shared好处
(1)使用make_shared最大的好处就是减少单次内存分配的次数
(2)另一个好处就是可以增大Cache局部性(Cache Locality):使用make_shared,计数器的内存和原生内存就在堆上排排坐,这样的话我们所有要访问这两个内存的操作就会比另一种方案减少一半的cache misses。
(3)在调用次数不定的情况下,对对象还处在管理阶段

#include<iostream>
#include<atomic>
#include<string>
#include<map>
#include<memory>
using namespace std;

class Object
{
private:
	int value;
public:
	Object(int x=0) :value(x) {}
	~Object() {}
	void Print() const
	{
		cout << value << endl;
	}
};
int main()
{
	//两种构建对象方式
	std::shared_ptr<Object> op1(new Object(10));
	std::shared_ptr<Object> op2 = std::make_shared<Object>(10);//对堆空间只构建一次

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值