我尝试根据培训材料中的类图实现访问者设计模式。我刚刚参加过这次培训,但我没有保存我在那里实施的代码。我陷入了编译错误,我无法弄清楚我做错了什么。很可能我并不了解这种设计模式的类图。下面我把整个代码和我收到的编译错误。
#define _USE_MATH_DEFINES
#include <list>
#include "math.h"
class Cerc;
class Dreptunghi;
class Arie;
class Perimetru;
class Operatie;
class Forma
{
public:
virtual void accept(Operatie * op);
Forma(void){};
~Forma(void){};
};
class Cerc : public Forma {
protected:
int raza;
public:
void accept(Operatie * op){op->vizitare(this);};
int getRaza(){return raza;};
Cerc(void):raza(3){};
~Cerc(void){};
};
class Dreptunghi : public Forma {
protected:
int lungime;
int latime;
public:
void accept(Operatie * op){op->vizitare(this);};
int getLungime(void){return lungime;};
int getLatime(void){return latime;};
Dreptunghi(void):lungime(3),latime(3){};
~Dreptunghi(void){};
};
class Operatie{
public:
virtual void vizitare(Cerc* obj) = 0;
virtual void vizitare(Dreptunghi* obj) = 0;
Operatie(void){};
~Operatie(void){};
};
class Arie : public Operatie {
private:
double arie;
public:
double getResult(){return arie;};
void vizitare(Cerc* obj){arie = arie + M_PI*obj->getRaza();};
void vizitare(Dreptunghi* obj){arie = arie + obj->getLungime() + obj->getLatime();};
Arie(void): arie(0) {};
~Arie(void){};
};
class Perimetru : public Operatie {
private:
double perimetru;
public:
double getResult(){return perimetru;};
void vizitare(Cerc* obj){perimetru = perimetru + M_PI*obj->getRaza()*obj->getRaza();};
void vizitare(Dreptunghi* obj){perimetru = perimetru + 2*(obj->getLungime() + obj->getLatime());};
Perimetru(void):perimetru(0){};
~Perimetru(void){};
};
class Editor{
private:
std::list<Forma*> forme;
public:
Editor(void){};
void insert(Forma obj){forme.insert(forme.end(), &obj);};
double calculeazaArieTotala(){
Arie arie;
for(std::list<Forma *>::iterator it = forme.begin(); it != forme.end(); ++it){
(*it)->accept(&arie);
}
return arie.getResult();
};
double calculeazaPerimetrulTotal(){
Perimetru permietru;
for(std::list<Forma *>::iterator it = forme.begin(); it != forme.end(); ++it){
(*it)->accept(&permietru);
}
return permietru.getResult();
};
~Editor(void){};
};
int main(void){
Editor editor;
cout << editor.calculeazaArieTotala() << endl;
cout << editor.calculeazaPerimetrulTotal() << endl;
}
我得到的编译器错误:
visitordesignpattern.cpp(23): error C2027: use of undefined type 'Operatie'
visitordesignpattern.cpp(23) : see declaration of 'Operatie'
visitordesignpattern.cpp(23) error C2227: left of '->vizitare' must point to class/struct/union/generic type
visitordesignpattern.cpp(23) error C2027: use of undefined type 'Operatie'
visitordesignpattern.cpp(23) see declaration of 'Operatie'
visitordesignpattern.cpp(23) error C2227: left of '->vizitare' must point to class/struct/union/generic type
谢谢!
答案 0 :(得分:2)
当您撰写op->vizitare(this);
时,Operatie
的类型必须为complete,即之前必须显示其定义;只有前瞻性声明是不够的。
将Operatie
的定义移到它之前。 e.g。
... ...
class Operatie{
public:
virtual void vizitare(Cerc* obj) = 0;
virtual void vizitare(Dreptunghi* obj) = 0;
Operatie(void){};
~Operatie(void){};
};
class Cerc : public Forma {
protected:
int raza;
public:
void accept(Operatie * op){op->vizitare(this);};
int getRaza(){return raza;};
Cerc(void):raza(3){};
~Cerc(void){};
};
class Dreptunghi : public Forma {
protected:
int lungime;
int latime;
public:
void accept(Operatie * op){op->vizitare(this);};
int getLungime(void){return lungime;};
int getLatime(void){return latime;};
Dreptunghi(void):lungime(3),latime(3){};
~Dreptunghi(void){};
};
... ...
答案 1 :(得分:0)
只需将Operatie的定义移到代码的开头即可。
答案 2 :(得分:0)
您的代码中有两个错误!正如 songyuanyao 所说,调整你的代码安排!第二个错误是在文件头添加iostream
!完整代码如下所示
#define _USE_MATH_DEFINES
#include <list>
#include "math.h"
#include <iostream>
using namespace std;
class Dreptunghi;
class Arie;
class Perimetru;
class Operatie;
class Cerc;
class Forma
{
public:
virtual void accept(Operatie * op);
Forma(void){};
~Forma(void){};
};
class Operatie{
public:
virtual void vizitare(Cerc* obj) = 0;
virtual void vizitare(Dreptunghi* obj) = 0;
Operatie(void){};
~Operatie(void){};
};
class Cerc : public Forma {
protected:
int raza;
public:
void accept(Operatie* op){op->vizitare(this);};
int getRaza(){return raza;};
Cerc(void):raza(3){};
~Cerc(void){};
};
class Dreptunghi : public Forma {
protected:
int lungime;
int latime;
public:
void accept(Operatie * op){op->vizitare(this);};
int getLungime(void){return lungime;};
int getLatime(void){return latime;};
Dreptunghi(void):lungime(3),latime(3){};
~Dreptunghi(void){};
};
class Arie : public Operatie {
private:
double arie;
public:
double getResult(){return arie;};
void vizitare(Cerc* obj){arie = arie + M_PI*obj->getRaza();};
void vizitare(Dreptunghi* obj){arie = arie + obj->getLungime() + obj->getLatime();};
Arie(void): arie(0) {};
~Arie(void){};
};
class Perimetru : public Operatie {
private:
double perimetru;
public:
double getResult(){return perimetru;};
void vizitare(Cerc* obj){perimetru = perimetru + M_PI*obj->getRaza()*obj->getRaza();};
void vizitare(Dreptunghi* obj){perimetru = perimetru + 2*(obj->getLungime() + obj->getLatime());};
Perimetru(void):perimetru(0){};
~Perimetru(void){};
};
class Editor{
private:
std::list<Forma*> forme;
public:
Editor(void){};
void insert(Forma obj){forme.insert(forme.end(), &obj);};
double calculeazaArieTotala(){
Arie arie;
for(std::list<Forma *>::iterator it = forme.begin(); it != forme.end(); ++it){
(*it)->accept(&arie);
}
return arie.getResult();
};
double calculeazaPerimetrulTotal(){
Perimetru permietru;
for(std::list<Forma *>::iterator it = forme.begin(); it != forme.end(); ++it){
(*it)->accept(&permietru);
}
return permietru.getResult();
};
~Editor(void){};
};
int main(void){
Editor editor;
cout << editor.calculeazaArieTotala() << endl;
cout << editor.calculeazaPerimetrulTotal() << endl;
}