Template class Verständnisproblem

Swebble

Mitglied
Hallo und guten Morgen Forum,

gleich vorneweg: Ich bin Java-Entwickler und daher mit C++ nicht allzu vertraut. Also seit bitte ein wenig nachsichtig mit mir ;)

Ich versuche gerade eine Klassenhierarchie mit templates zu realisieren und zwar zum Thema CRC-Berechnung. In Java würde ich dazu ein Interface definieren, welches die Schnittstelle festlegt und dann für jede CRC-Spezialisierung eine Klasse erstellen, welche dieses Interface implementiert. Soweit so gut.
Da es in C++ keine Interfaces gibt (soweit mein Kenntnisstand jedenfalls), dachte ich an folgende Lösungsmöglichkeit:

Eine Basisklasse mit generischem Typ:
Code:
#ifndef _CRC_H_
#define _CRC_H_

#include <vector>

using namespace std;

template<typename T>
class CRC
{
public:
	virtual void update(unsigned char c);
	virtual void update(vector<unsigned char> p_cvData);
	virtual void update(vector<unsigned char> p_cvData, unsigned int p_iOffset, unsigned int p_iLength);

	virtual void reset(void);

	virtual T getValue();

protected:
	T m_preset;
	T m_crc;
};

#endif

Davon dann abgeleitet verschiedene spezialisierte Klassen für einzelne CRC-Berechnungen. Zum Beispiel:
Code:
#ifndef _CRC8_H_
#define _CRC8_H_

#include "CRC.h"
#include <vector>

using namespace std;

class CRC8 : public CRC<unsigned char>
{
public:
	CRC8(unsigned char p_cPreset, unsigned char p_cPolynom);
	
	virtual void update(unsigned char c);
	virtual void update(vector<unsigned char> p_cvData);
	virtual void update(vector<unsigned char> p_cvData, unsigned int p_iOffset, unsigned int p_iLength);

	virtual void reset(void);

	virtual unsigned char getValue();

private:
	unsigned char m_cPolynom;
};

#endif

oder auch:

Code:
#ifndef _CRC32_H_
#define _CRC32_H_

#include "CRC.h"
#include <vector>

using namespace std;

class CRC32 : public CRC<unsigned int>
{
public:
	CRC32(unsigned int p_uiPreset = 0xFFFFFFFF);
	
	virtual void update(unsigned char p_ucData);
	virtual void update(vector<unsigned char> p_cvData);
	virtual void update(vector<unsigned char> p_cvData, unsigned int p_iOffset, unsigned int p_iLength);

	virtual void reset(void);

	virtual unsigned int getValue();

private:
	static const unsigned int CRC_TABLE[256];
};

#endif

Soweit hat der Compiler das auch übersetzt. Juhu, dachte ich zuerst. Aber bei der Verwendung dieser Klassen gibt es nun das folgende Problem:
Code:
CRC crc;
unsigned int uiCrcLen = 1;
switch(crcType)
{
	case CRCInfo::CRC8:
		crc = CRC8(0xC7, 0x1D);
		uiCrcLen = 1;
	break;
	case CRCInfo::CRC16:
		crc = CRC16();
		uiCrcLen = 2;
	break;
	case CRCInfo::CRC32:
		crc = CRC32();
		uiCrcLen = 4;
	break;
}

error C2955: "CRC": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.

Ist vermutlich nur ein Denkfehler eines Java-Programmierers. Trotzdem würde ich das gerne so machen. Hat jemand einen Hinweis dazu?

Vielen Dank,


Sebastian
 
Hi.
Ich versuche gerade eine Klassenhierarchie mit templates zu realisieren und zwar zum Thema CRC-Berechnung. In Java würde ich dazu ein Interface definieren, welches die Schnittstelle festlegt und dann für jede CRC-Spezialisierung eine Klasse erstellen, welche dieses Interface implementiert. Soweit so gut.
Da es in C++ keine Interfaces gibt
Nur weil es in C++ kein Sprachmittel für Schnittstellen gibt, heißt das nicht das man keine Schnittstellen in C++ erstellen kann. Erstelle einfach eine abstrakte Basisklasse.
Soweit hat der Compiler das auch übersetzt. Juhu, dachte ich zuerst. Aber bei der Verwendung dieser Klassen gibt es nun das folgende Problem:
Code:
CRC crc;
unsigned int uiCrcLen = 1;
switch(crcType)
{
	case CRCInfo::CRC8:
		crc = CRC8(0xC7, 0x1D);
		uiCrcLen = 1;
	break;
	case CRCInfo::CRC16:
		crc = CRC16();
		uiCrcLen = 2;
	break;
	case CRCInfo::CRC32:
		crc = CRC32();
		uiCrcLen = 4;
	break;
}

error C2955: "CRC": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.

Ist vermutlich nur ein Denkfehler eines Java-Programmierers. Trotzdem würde ich das gerne so machen. Hat jemand einen Hinweis dazu?
Wie der Compiler schon sagte: CRC ist eine Template-Klasse (also unvollständig) und du müßtest eine Instanz dieses Templates erzeugen um sie benutzen zu können.

Außerdem haben deine CRC8, CRC16 und CRC32 Klassen vererbungstechnisch überhaupt nichts miteinander zu tun, da sie alle von völlig verschiedenen Basisklassen erben (CRC<char> ist verschieden von CRC<unsigned> usw.).

Selbst wenn all das erlaubt wäre, würde die Zuweisung crc = CRC8(0xC7, 0x1D); dazu führen, das ein CRC8 in ein crc umgewandelt werden würde. D.h. crc wäre in dem Fall kein CRC8 - es wäre immer nur ein CRC. Polymorphie funktioniert in C++ nur mit Referenzen und Zeigern, du mußt also mit Zeiger arbeiten.

Definiere einfach eine abstrakte Basisklasse (ein Interface) und leite davon deine Unterklassen ab.

Gruß
 
Hallo deepthroat,

das heißt also das ganze template Zeugs ist an der Stelle überflüssig? Eine gemeinsame abstrakte Klasse reicht völlig. Aber wie definiere ich eine gemeinsame Methode getValue(), welche bei den einzelnen abgeleiteten Klassen unterschiedliche Rückgabetypen haben?

Code:
virtual T getValue();
 
Aber wie definiere ich eine gemeinsame Methode getValue(), welche bei den einzelnen abgeleiteten Klassen unterschiedliche Rückgabetypen haben?

Code:
virtual T getValue();
Das geht natürlich nicht. Außerdem mußt du sowieso immer wissen um welche konkrete CRC es sich handelt. So kannst du genauso gut die Methode nur in den Unterklassen deklarieren.

Was ist denn das Ziel bzw. der Anwendungsfall für die CRC Klasse?

Gruß
 
Zurück