c++设计模式
代理模式:为其它对象提供一种代理以控制这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
优点:
- 职责清晰。真实的角色只负责实现实际的业务逻辑,不用关心其它非本职责的事务,通过后期的代理完成具体的任务。这样代码会简洁清晰。
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样就保护了目标对象。
- 扩展性好。
分类:
代理模式
- 虚拟代理:是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,使其只有在真正需要时才被创建。
- 远程代理:为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。这个不同的地址空间可以是在本机器上,也可以在另一台机器中。
- 智能引用代理:是指当调用真实对象时,代理处理另外一些事,比如记录对此对象的调用次数等。
- 安全代理:也叫保护代理,用来控制真实对象访问时的权限,如果有必要的话,可以给不同调用者提供不同的权限。
- 写时拷贝代理:虚拟代理的一种,把复制推迟到只有客户的需要时才进行。
- 缓存代理:为某一个目标的操作结果提供临时存储空间,以便其他客户的可以共享访问,有点缓存的味道。
- 防火墙代理:保护对象,不让用户访问,安全代理的特例。 •同步代理:可以让几个用户同时访问同一个对象而不产生冲突。
1,虚拟代理
虚拟代理的主要目的是实现延迟,考虑一个可以在文档中嵌入图形对象的文档编辑器。有些图形对象的创建开销很大。但是打开文档必须很迅速,因此我们在打开文档时应避免一次性创建所有开销很大的对象。这里就可以运用代理模式,在打开文档时,并不打开图形对象,而是打开图形对象的代理以替代真实的图形。待到真正需要打开图形时,仍由代理负责打开。
2,代码示例
2.1,目录结构
2.2,cmake
cmake_minimum_required(VERSION 3.5)
project(app)
if(CMAKE_COMPILER_IS_GNUCC)
message("COMPILER IS GNUCC")
ADD_DEFINITIONS ( -std=c++11 )
endif(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -ggdb3")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# 3. opencv
link_directories("/usr/local/lib")
include_directories("/usr/local/include/opencv4")
include_directories(${CMAKE_SOURCE_DIR})
# 6. 添加源文件
FILE(GLOB SOURCE_FILES ${CMAKE_SOURCE_DIR}/*.cpp )
message(${CMAKE_SOURCE_DIR})
message(${SOURCE_FILES})
# 7. 添加链接库
LINK_LIBRARIES(opencv_core opencv_highgui opencv_imgcodecs)
# 9. 设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,
#但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
SET(ALL_SRCS ${SOURCE_FILES})
message(${ALL_SRCS})
# 10.add executable file,添加要编译的可执行文件
ADD_EXECUTABLE(${PROJECT_NAME} ${ALL_SRCS})
2.3,main.cpp
#include <iostream>
#include <sys/stat.h>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
bool isFileExist(std::string file_name) {
struct stat buffer;
return (stat(file_name.c_str(), &buffer) == 0)?true:false;
}
class Image {
public:
Image(std::string name) : m_name(name) {};
virtual ~Image() {std::cout << "Image destructor" << std::endl;};
virtual void show() = 0;
protected:
std::string m_name;
};
class BigImage : public Image {
public:
using Image::Image;
virtual ~BigImage() {std::cout << "BigImage destructor" << std::endl;};
void show() override {
if(!isFileExist(m_name)) {throw std::string("file is not existed!");}
cv::Mat temp = cv::imread(m_name);
if(temp.empty()) {std::cerr << "the image:"<< m_name <<" is empty!" << std::endl; return;}
cv::imshow(m_name, temp);
};
};
class BigImageProxy : public Image {
public:
BigImageProxy(std::string name) : Image(name) {m_bigimage = nullptr;};
virtual ~BigImageProxy() {std::cout << "BigImageProxy destructor" << std::endl; delete m_bigimage;};
void show() override {
if(m_bigimage == nullptr) m_bigimage = new BigImage(m_name);
m_bigimage->show();
};
private:
BigImage *m_bigimage;
};
int main() {
std::string image_path = "/home/wangxy/test_code/algorithm_avsstreamer/test_data/utils/device_data/image203.jpg";
BigImageProxy bigimage_proxy(image_path);
bigimage_proxy.show();
return 0;
}