一、组成
抽象类:声明功能接口,维护实现类的引用。
扩展抽象类:调用实现类功能接口,并实现自己的功能接口。
实现类:声明功能接口。
具体实现类:实现功能接口。
二、特点
1、抽象类包含实现类接口构成“桥”。
2、抽象类对实现类的引用以受保护的权限给子类继承。
三、目的
紧密相关的类拆分成抽象和实现两个独立的层次结构,通过组合的方式来代替继承。
四、缺点
1、性能问题,频繁的调用抽象类时,抽象类与实现类对象的引用关系有一定的性能损耗。
2、场景限制问题,适用于两个以上独立变化维度的情况。
五、示例代码
#include<iostream>
#include <vector>
#include <list>
#include <string>
#include <mutex>
#include <map>
#include<stack>using namespace std;class ImageOs;//实现类
class ImageOs_Windows;//具体实现类
class ImageOs_Linux; //具体实现类
class Image;//抽象类
class Image_PNG;//扩展抽象类
class Image_BMP; //扩展抽象类//实现类
class ImageOs {
public:virtual void draw(const char* pData, int len) = 0;virtual ~ImageOs() {cout << "~ImageOs" << endl;};
};
//具体实现类
class ImageOs_Windows : public ImageOs {
public:void draw(const char* pData, int len) {cout << "A picture was drawn on the Windows system" << endl;};~ImageOs_Windows() {cout << "~ImageOs_Windows" << endl;};
};class ImageOs_Linux : public ImageOs {
public:void draw(const char* pData, int len) {cout << "A picture was drawn on the Linux system" << endl;};~ImageOs_Linux() {cout << "~ImageOs_Linux" << endl;};
};//抽象类
class Image {
public:Image(ImageOs* imageOs) : m_imageOs(imageOs) {};virtual void parseFile(const char* pFileName) = 0;virtual ~Image() {cout << "~Image" << endl;};
protected:ImageOs* m_imageOs;//抽象类包含实现类接口构成“桥”
};//扩展抽象类
class Image_PNG : public Image {
public:Image_PNG(ImageOs* imageOs) : Image(imageOs) {}void parseFile(const char* pFileName) {char* pData = nullptr;int len = 0;cout << "Analyzed an image in PNG format" << endl;m_imageOs->draw(pData, len);};~Image_PNG() {cout << "~Image_PNG" << endl;}
};class Image_BMP : public Image {
public:Image_BMP(ImageOs* imageOs) : Image(imageOs) {}void parseFile(const char* pFileName) {char* pData = nullptr;int len = 0;cout << "Analyzed an image in BMP format" << endl;m_imageOs->draw(pData, len);};~Image_BMP() {cout << "~Image_BMP" << endl;}
};int main() {unique_ptr<ImageOs> imageOs_Windows = make_unique<ImageOs_Windows>();unique_ptr<ImageOs> imageOs_Linux = make_unique<ImageOs_Linux>();unique_ptr<Image_PNG> image_PNG = make_unique<Image_PNG>(imageOs_Windows.get());unique_ptr<Image_BMP> image_BMP = make_unique<Image_BMP>(imageOs_Linux.get());image_PNG->parseFile("1.png");image_BMP->parseFile("1.bmp");
}