代理模式: 为其他对象提供一个代理以控制对这个对象的访问
使用场景:
- 远程代理
- 虚代理
- 保护代理
- ...后续补充使用场景
举例
考虑一个可以在文档中镶嵌图形对象的文档编辑器,有些图形对象的创建开销很大, 但是打开文档必须很迅速, 因此我们在打开文档时应该避免一次性创建所有开销很大的对象。这里就可以运用代理模式。在打开文档时候, 并不打开图形对象。而是打开图形对象的代理以代替真实的图形,待到真正需要打开图形时,仍由代理负责打开, 下面给出UML图:
简单实现
class Image{
public:
Image(string name):m_imageName(name){}
virtual ~Image()
virtual void show() {}
protected:
string m_imageName;
};
class BigImage: public Image {
public:
BigImage(string name):Image(name){}
~BigImage(){}
viod show(){cout <<" show big Image: " << m_imageName << endl;}
};
class BigImageProxy:public Image{
private:
BigImage* m_bigImage;
public:
BigImageProxy(string name):Image(name): m_bigImage(nullptr){}
~BigImageProxy(){delete m_bigImage;}
void show()
{
if(m_bigImage == nullptr){
m_bigImage = new BigImage(m_imageName);
m_bigImage->show() ;
}
}
};
int main(){
Image * iamge = new BigImageProxy("proxy.jpg");
image->show();
delete image;
return 0;
}
在这个例子属于虚代理的情况; 下面给出两个只能引用的例子。
class auto_ptr {
public:
explicit auto_ptr(T* p = 0) : pointee_(p) {}
auto_ptr(auto_ptr<T>& rhs) : pointee_(rhs.release()) {}
~auto_ptr() { delete pointee_; }
auto_ptr<T>& operator=(auto_ptr<T>& rhs) {
if (this != &rhs) reset(rhs.release());
return *this;
}
T& operator*() const { return *pointee_; }
T* operator->() const { return pointee_; }
T* get() const { return pointee_; }
T* release() {
T* oldPointee = pointee_;
pointee_ = 0;
return oldPointee;
}
void reset(T* p = 0) {
if (pointee_ != p) {
delete pointee_;
pointee_ = p;
}
}
private:
T* pointee_;
};
smart_ptr
template <typename T>
class smart_ptr {
private:
T* pointee_;
size_t* count_;
void decr_count() {
if (--*count_ == 0) {
delete pointee_;
delete count_;
}
}
public:
smart_ptr(T* p = 0) : pointee_(p), count_(new size_t(1)) {}
smart_ptr(const smart_ptr& rhs) : pointee_(rhs.pointee_), count_(rhs.count_) { ++*count_; }
~smart_ptr() { decr_count(); }
smart_ptr& operator=(const smart_ptr& rhs) {
if (this == &rhs) {
return *this;
}
decr_count();
pointee_ = rhs.pointee_;
count_ = rhs.count_;
*count_ = *count_ + 1;
return *this;
}
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。