值对象是一种对象。我们只关心它的值,不关心到底是哪一个。简单的说,如果两个对象的值相等,我们就认为这两个对象“相等”。
现实世界中的值对象的例子: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是两个钢镚,它们是两个句柄对象,背后指向同一个对象。