허구 함수
그 밖에 구조 함수 호출 기간에 가상 메커니즘은 작용하지 않는다(조기 귀속 발생).어떤 경우에 이것은 매우 까다로운 일이다.예를 들어 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++ 프로그래밍 사상에서 뽑다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.