DesignPattern-part3

title: "modern C++ DesignPattern-Part3"
date: 2018-04-12T19:08:49+08:00
lastmod: 2018-04-12T19:08:49+08:00
keywords: [设计模式, C++]
tags: [设计模式]
categories: []

结构式设计模式的最后两个,享元模式:实现对象共享,减少内存开销;代理模式,提供相同接口的代理

flyweight

享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。boost::flyweight使用:

struct User2
{
 flyweight<string> first_name, last_name; //类似一个缓存
 User2(const string &first_name, const string &last_name)
 : first_name(first_name),
 last_name(last_name) {}
};
void boost_flyweight()
{
 User2 user1{"John", "Smith"};
 User2 user2{"Jane", "Smith"};
 cout << user1.first_name << endl;
 cout << boolalpha //std::boolalpha可以把bool变成true/false字符串
 << (&user1.first_name.get() == &user2.first_name.get()) << endl;
 cout << boolalpha
 << (&user1.last_name.get() == &user2.last_name.get()) << endl;
}

示例:

class FormattedText { //用来记录是否被复用的单元
 string plain_text;
 bool *caps;
public:
 explicit FormattedText(const string &plainText)
 : plain_text{plainText} {
 caps = new bool[plainText.length()];
 memset(caps, 0, plain_text.length());
 }
 ~FormattedText() {
 delete[] caps;
 }
 void capitalize(int start, int end) {
 for (int i = start; i <= end; ++i)
 caps[i] = true;
 }
 friend std::ostream &operator<<(std::ostream &os, const FormattedText &obj) {
 string s;
 for (int i = 0; i < obj.plain_text.length(); ++i) {
 char c = obj.plain_text[i];
 s += (obj.caps[i] ? toupper(c) : c);
 }
 return os << s;
 }
};
class BetterFormattedText {
public:
 struct TextRange {
 int start, end;
 bool capitalize, bold, italic;
 bool covers(int position) const {
 return position >= start && position <= end;
 }
 };
 TextRange &get_range(int start, int end) { //每当设置一个被复用的单元,push到vector里面,返回最后一个
 formatting.emplace_back(TextRange{start, end});
 return *formatting.rbegin();
 }
 explicit BetterFormattedText(const string &plainText)
 : plain_text{plainText} {
 }
 friend std::ostream &operator<<(std::ostream &os, const BetterFormattedText &obj) {
 string s;
 for (size_t i = 0; i < obj.plain_text.length(); i++) {
 auto c = obj.plain_text[i];
 for (const auto &rng : obj.formatting) {
 if (rng.covers(i) && rng.capitalize)
 c = toupper(c);
 }
 s += c; // fixed!
 }
 return os << s;
 }
private:
 string plain_text;
 vector<TextRange> formatting;
};

Proxy

代理模式最经典的是shared_ptr实现,增加了引用计数的同时保持了原有的普通指针接口

Property Proxy

template <typename T> struct Property {
 T value;
 Property(const T initialValue) {
 *this = initialValue;
 }
 operator T() { //getter
 return value;
 }
 T operator =(T newValue) { //setter
 return value = newValue;
 }
};
//usage
struct Creature
{
 Property<int> strength{ 10 };
 Property<int> agility{ 5 };
};
void property_proxy() {
 Creature creature;
 creature.agility = 20;
 cout << creature.agility << endl;
}

主要目的是可以允许 Property<int>与int的随时转换。

Virtual Proxy

这种非常常见,使用时分两种,eager模式和lazy模式,区别就是lazy模式是在使用的时候才会初始化

struct Image{
 virtual ~Image() = default;
 virtual void draw() = 0;
};
struct Bitmap : Image{
 Bitmap(const string& filename) {
 cout << "Loading image from " << filename << endl;
 }
 void draw() override {
 cout << "Drawing image" << endl;
 }
};
struct LazyBitmap : Image {
 LazyBitmap(const string& filename): filename(filename) {}
 ~LazyBitmap() { delete bmp; }
 void draw() override {
 if (!bmp)
 bmp = new Bitmap(filename);
 bmp->draw();
 }
private:
 Bitmap* bmp{nullptr};
 string filename;
};
void draw_image(Image& img) {
 img.draw();
}
void virtual_proxy() {
 LazyBitmap img{ "pokemon.png" };
 draw_image(img); // loaded whether the bitmap is loaded or not
 draw_image(img);
}
作者:SunStriKE原文地址:https://www.cnblogs.com/sunstrikes/p/17253112.html

%s 个评论

要回复文章请先登录注册