Bridge パターン

Bridge パターン - Wikipedia
「実装のクラス階層(Implementor)」と「機能のクラス階層(Abstraction)」を分けて、2つの独立したクラス階層にする。

ついでに参照とポインタの関係も怪しかったのでいろいろやった。

#include<iostream>
#include<string>
using namespace std;
//Implementor
class DisplayImpl
{
public :
	virtual void RawPrint() const = 0;
	virtual void RawOpen() const = 0;
	virtual void RawClose() const = 0;
};
//Concrete Implementor
class StringDisplayImpl : public DisplayImpl
{
public :
	StringDisplayImpl(string str){
		this->string_ = str;
	}
	void RawPrint() const{
		cout << "|" << this->string_. c_str() << "|" << endl;
	}
	void RawOpen() const{
		PrintLine();	
	}
	void RawClose() const{
		PrintLine();		
	}
private :
	string string_;

	void PrintLine() const{
		cout << "+";
		for(unsigned int i = 0; i < string_.length(); i++){
			cout << "-";
		}
		cout << "+" << endl;
	}
};
//Abstraction
class Display
{
public :
	Display(const DisplayImpl * display_impl): display_impl_(display_impl){
	}
	virtual ~Display(){
		delete display_impl_;
	}
	void Print() const{
		display_impl_->RawPrint();
	}
	void Open() const{
		display_impl_->RawOpen();
	}
	void Close() const{
		display_impl_->RawClose();
	}
	void Show(){
		Open();
		Print();
		Close();
	}
private :
	const DisplayImpl *display_impl_;
};
//Refined Abstraction
class CountDisplay : public Display
{
public :
	CountDisplay(const DisplayImpl * display_impl) : Display(display_impl){
	}
	void MultiShow(int times) const{
		Open();
		for(int i = 0; i < times; i++){
			Print();
		}
		Close();
	}
};
//main
int main()
{
	Display *d1      = new Display(new StringDisplayImpl("Hello, Japan. pointer"));
	Display &d2      =     Display(new StringDisplayImpl("Hello, Japan. reference"));
	Display *d3      = new CountDisplay(new StringDisplayImpl("Hello, World. pointer"));
	Display &d4      =     CountDisplay(new StringDisplayImpl("Hello, World. reference"));
	CountDisplay *d5 = new CountDisplay(new StringDisplayImpl("Hello, Universe. pointer"));
	CountDisplay &d6 =     CountDisplay(new StringDisplayImpl("Hello, Universe. reference"));
	d1->Show();
	d2.Show();
	d3->Show();
	d4.Show();
	d5->Show();
	d6.Show();
	d5->MultiShow(5);
	d6.MultiShow(5);
	
	delete d1;
	delete d3;
	delete d5;
	return 0;
}