学习笔记: 享元模式和值对象

本文探讨了如何通过享元模式减少内存消耗,以钢镚对象为例,展示了如何利用句柄技术实现对象复用,节省资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

值对象是一种对象。我们只关心它的值,不关心到底是哪一个。简单的说,如果两个对象的值相等,我们就认为这两个对象“相等”。

现实世界中的值对象的例子:1元钢镚。我们只看钢镚的面值是1元,不管钢镚的新旧。

对应的,还存在“实体对象”,两个“实体对象”是否相等的唯一判断标准是:ID相同。

现实世界的“实体对象”的例子:100元钞票。我们一般要关心其唯一编号,防止某些假钞。

假设在计算机系统中表示10000个钢镚,需要建立10000个钢镚对象。

我们发现,钢镚就1毛,5毛,1元这常见的三种,不用浪费大量内存记录重复的信息。因此想到某种”句柄“技术,来解决这个问题。

#include <boost/flyweight.hpp>
#include <boost/functional/hash.hpp>
using namespace std;

#include <iostream>
#include <cassert>

//钢镚对象
class Coin{
public:
	Coin(int i){
	    amount_=i;
		std::cout<<"Coin()"<<std::endl;
		if (i==50){
		    material_ = "铜";
			di_=20;
		}
		else if (i==100){
		    material_ = "镍";
			di_=30;
		}
		else if (i==10){
		    material_ = "铝";
			di_=10;
		}
	}

	~Coin(){
	    std::cout<<"~Coin()"<<std::endl;
	}

	int amount_; //钢镚面额
	std::string material_ ; //材质
	double di_ ; //钢镚直径
};

std::size_t hash_value(Coin const& b)
{
    boost::hash<int> hasher;
    return hasher(b.amount_);
}

bool operator==(const Coin& a, const Coin& b){
    return a.amount_ == b.amount_;
}

void  main()
{
    boost::flyweight<Coin> a(50);
    boost::flyweight<Coin> b(100);
    boost::flyweight<Coin> c(100);
	
    const Coin* addra = std::addressof(a.get());
    const Coin* addrb = std::addressof(b.get());
    const Coin* addrc = std::addressof(c.get());
	
    assert(addra!=addrb);
    assert(addrb==addrc);

    return ;
}
享元模式,就是最著名的一个,能节省大量内存的技术。
b,c是两个钢镚,它们是两个句柄对象,背后指向同一个对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值