05.05.2018, 13:06 |
Auf diesen Beitrag antworten » |
InformaTiger |
Vererbung in C++
Liebes Forum,
ich bin ein relativ erfahrener Java Programmierer weswegen mir folgendes Szenario in C++ etwas Schwierigkeiten bereitet. Ich habe eine Klassenstruktur für einige Parser und deren EventListener. Soweit ich das mitbekommen habe ist es in C++ nicht möglich etwas wie template<class T extends Entity> zu deklarieren aus diversen Kompilergründen. Beziehungsweise ist es schon möglich aber nur über den Umweg von static_casts und dererlei Funktionen.
Jetzt habe ich klarerweise das Problem, dass ich auch die Parser-Implementierungen wie bspw. BlockParser der eigentlich ein Parser<Block> ist und von Parser<Entity> erben müsste (Entity ist die Basisklasse von Block, Tag und Attribute) nicht in einen Parser<Entity> umwandeln kann (außer durch expliziten cast, wie ich das bisher umgesetzt habe). Und auch, dass ich auf meinem Scanner in der Methode add_parser(Parser<Entity>* parser) kein parser->add_listener(this) aufrufen kann weil der Scanner ja lediglich ein Block und TagEventListener ist.
Hat jemand eine Idee wie ich das geschickt lösen könnte?
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
|
// parser.h
#include "entity.h"
template <class T>
class ParserEventListener {
public:
virtual void update(T entity) = 0;
};
template <class T>
class Parser {
public:
virtual void add_listener(ParserEventListener<T*>* listener) = 0;
virtual void remove_listener(ParserEventListener<T*>* listener) = 0;
virtual void consume(char c, int pos) = 0;
virtual Array<T*>* get_result() = 0;
virtual void reset() = 0;
};
template <class T>
class AbstractParser: public Parser<T>, public ParserEventListener<T*> {
public:
static const int ZERO_STATE = 0;
AbstractParser();
virtual ~AbstractParser();
void add_listener(ParserEventListener<T*>* listener);
void remove_listener(ParserEventListener<T*>* listener);
void update(T* entity);
virtual void consume(char c, int pos) = 0;
Array<T*>* get_result();
virtual void reset() = 0;
protected:
void add_context(T* value);
bool has_state(int n, ...);
int _state;
private:
Array<ParserEventListener<T*>*> _listeners;
Array<T*> _context;
}; |
|
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
|
// scanner.h
#include "entity.h"
#include "parser.h"
#define CAPACITY 16
#define BUFFER_SIZE 1024
class Scanner: public ParserEventListener<Block*>, public ParserEventListener<Tag*>{
public:
Scanner();
~Scanner();
void add_parser(Parser<Entity>* parser);
void update(Block* block);
void update(Tag* tag);
Array<Entity*>* scan(char* source);
private:
Array<char>* read_source(char* source);
Array<Entity*>* get_document();
Block* _last_block;
Array<Parser<Entity>*> _context;
}; |
|
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
|
// wsc.cpp
#include "parser.h"
#include "scanner.h"
using std::cout;
using std::cerr;
using std::endl;
void ws_export(Array<Entity*>*, std::string);
std::string ws_name(std::string);
int main(int argc, char** argv){
Scanner scn;
try {
Parser<Entity>* parser = (Parser<Entity>*)new BlockParser;
scn.add_parser(parser);
parser = (Parser<Entity>*)new TagParser;
scn.add_parser(parser);
Array<Entity*>* doc = scn.scan(argv[1]);
ws_export(doc, argv[1]);
array_free(doc, true);
} catch (const char* msg){
cerr << msg << endl;
}
return EXIT_SUCCESS;
} |
|
Danke schonmal im voraus
Mit freundlichen Grüßen
InformaTiger |