허구 함수

4324 단어
공장 방법 모델을 사용하는 주요 목표 중 하나는 코드를 더욱 잘 조직하여 대상을 만들 때 정확한 구조 함수 유형을 선택할 필요가 없도록 하는 것이다.즉, 공장에 "아직 어떤 유형의 대상이 필요한지 정확히 알 수는 없지만 여기에 정보가 있습니다. 적당한 유형의 대상을 만들어 주세요."라고 알려줄 수 있다.
그 밖에 구조 함수 호출 기간에 가상 메커니즘은 작용하지 않는다(조기 귀속 발생).어떤 경우에 이것은 매우 까다로운 일이다.예를 들어 Shape 프로그램에서 Shape 대상의 구조 함수 내부에 필요한 것을 만들어서draw()로 Shape를 만드는 것은 합리적인 것 같다.함수 draw()는 Shape에 전달되는 메시지에 따라 그래픽을 그릴 수 있는 허함수여야 하며, 메시지 자체는 Circle, Square 또는 Line임을 나타냅니다.그러나 이러한 조작은 구조 함수 내부에서 이런 방법을 사용할 수 없다. 왜냐하면 구조 함수 내부에서 허함수를 호출할 때 허함수가 어느'국부적'함수체를 가리키는지 결정하기 때문이다.
그러나 프로그래머는 때때로 허구조 함수에 가까운 행동을 원하기도 한다.
Coplien은 그가 제시한 문제 해결 방법을'봉투와 편지류'라는 이름으로 지었다.'봉투' 클래스는 기본 클래스입니다. 대상을 가리키는 바늘을 포함하는 케이스이며, 이 대상도 기본 클래스입니다.'봉투' 클래스의 구조 함수는 어떤 특정한 유형을 사용할지 결정하고, 무더기에 이 유형의 대상을 만들고, 그 바늘에 대한 분배 대상을 결정한다. (컴파일에서 형식 검사를 할 때가 아니라 실행 중 구조 함수를 호출할 때 결정된다.)이후의 모든 함수 호출은 기본 클래스가 바늘을 통해 처리합니다.이것은 사실상 상태 모델의 작은 변형이다. 그 중에서 기류는 파생류의 대리 역할을 하고 파생류는 행위의 변화를 제공한다.
#include <iostream>
#include <string>
#include <stdexcept>
#include <stdexcept>
#include <cstddef>
#include <vector>
//#include "../purge.h"
using namespace std;

class Shape {
	Shape* s;
	// Prevent copy-construction & operator=
	Shape(Shape&);
	Shape operator=(Shape&);
protected:
	Shape() { s = 0; }
public:
	virtual void draw() { s->draw(); }
	virtual void erase() { s->erase(); }
	virtual void test() { s->test(); }
	virtual ~Shape() {
		cout << "~Shape" << endl;
		if(s) {
			cout << "Making virtual call: ";
			s->erase(); // Virtual call
		}
		cout << "delete s: ";
		delete s; // The polymorphic deletion
		// (delete 0 is legal; it produces a no-op)
	}
	class BadShapeCreation : public logic_error {
	public:
		BadShapeCreation(string type)
			: logic_error("Cannot create type " + type) {}
	};
	Shape(string type) throw(BadShapeCreation);
};

class Circle : public Shape {
	Circle(Circle&);
	Circle operator=(Circle&);
	Circle() {} // Private constructor
	friend class Shape;
public:
	void draw() { cout << "Circle::draw" << endl; }
	void erase() { cout << "Circle::erase" << endl; }
	void test() { draw(); }
	~Circle() { cout << "Circle::~Circle" << endl; }
};

class Square : public Shape {
	Square(Square&);
	Square operator=(Square&);
	Square() {}
	friend class Shape;
public:
	void draw() { cout << "Square::draw" << endl; }
	void erase() { cout << "Square::erase" << endl; }
	void test() { draw(); }
	~Square() { cout << "Square::~Square" << endl; }
};

Shape::Shape(string type) throw(Shape::BadShapeCreation) {
	if(type == "Circle")
		s = new Circle;
	else if(type == "Square")
		s = new Square;
	else throw BadShapeCreation(type);
	draw();  // Virtual call in the constructor
}

char* sl[] = { "Circle", "Square", "Square",
	"Circle", "Circle", "Circle", "Square" };

int main() {
	vector<Shape*> shapes;
	cout << "virtual constructor calls:" << endl;
	try {
		for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++)
			shapes.push_back(new Shape(sl[i]));
	} catch(Shape::BadShapeCreation e) {
		cout << e.what() << endl;
		//purge(shapes);
		return EXIT_FAILURE;
	}
	for(size_t i = 0; i < shapes.size(); i++) {
		shapes[i]->draw();
		cout << "test" << endl;
		shapes[i]->test();
		cout << "end test" << endl;
		shapes[i]->erase();
	}
	Shape c("Circle"); // Create on the stack
	cout << "destructor calls:" << endl;
	//purge(shapes);
}
가상 함수 Shape (type) 는 모든 파생 클래스가 성명되기 전에 정의할 수 없습니다.
C++ 프로그래밍 사상에서 뽑다.

좋은 웹페이지 즐겨찾기