
#include <iostream>



class Visitor{
public:
	virtual ~Visitor(){}
	virtual void visitModelA(class ModelA*) = 0;
	virtual void visitModelB(class ModelB*) = 0;
	//add visit functions for later defined models
	
};





class View{
public:
	virtual ~View(){}
};

class ViewA : public View{
public:
	ViewA(){
		std::cout << "Created ViewA\n"; 
	}
};


class ViewB : public View{
public:
	ViewB(){
		std::cout << "Created ViewB\n"; 
	}
};








class Model{
public:
	virtual ~Model(){}

	virtual void Accept(Visitor* visitor) = 0;

};

class ModelA:public Model{
public:
	
	virtual void Accept(Visitor* visitor){
		visitor->visitModelA(this);
	}
};

class ModelB:public Model{
public:
	virtual void Accept(Visitor* visitor){
		visitor->visitModelB(this);
	}
};






// ViewCreator can be made a private class of ViewFactory
class ViewCreator : public Visitor{
public:
	virtual void visitModelA(class ModelA*) {
		_view = new ViewA();
	}
	virtual void visitModelB(class ModelB*) {
		_view = new ViewB();
	}
	
	//add visit functions for later defined models
	
	View* GetView(){
		return _view;
	}	

private:
	View* _view;
};


class ViewFactory{
public:
	static View* CreateViewFor( Model* model){
		ViewCreator viewCreator;
		model->Accept(&viewCreator);
		return viewCreator.GetView();
	}

};


int main(){

	ModelA modelA;
	View* viewA = ViewFactory::CreateViewFor(&modelA);
	
	
 	ModelB modelB;
	View* viewB = ViewFactory::CreateViewFor(&modelB);
	


}
