 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
CJ Guest
|
Posted: Mon Feb 27, 2006 8:06 pm Post subject: std::vector von abgeleiteten template-Klassen |
|
|
Hi!
Folgendes Problem:
Ich habe eine abstrakte Basisklasse, die eine Funktion beinhaltet, die
einen tamplate-Parameter besitzt.
z.B.:
template <class T>
class base
{
public:
base(){ };
virtual void machwas(T* wert) = 0;
};
Diese Klasse leite ich jetzt ab, so dass ich verschiedene Kind-Klassen
mit unterschiedlichen Klassen für T besitze.
Also z.B.:
class child1 : public base<int>
{
public:
child1() {};
void machwas(int* wert) {std::cout << *wert;};
};
oder auch
class child2 : public base<char>
etc.
Jetzt möchte ich eigentlich einen std::vector von allen instatiierten
Kind-Klassen anlegen.
Da diese aber unterschiedliche template-Werte haben, geht das
natürlich nicht.
Also habe ich folgendes probiert: std::vector von der gemeinsamen
Basisklasse.
std::vector<base> tVec;
Leider geht das auch nicht, da der template-Parameter ja unspezifiziert
ist.
Kann man überhaupt einen Vector von template-Klassen anlegen?
Wie geht das?
Vielen Dank für die Mühe!
CJ
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Mon Feb 27, 2006 10:06 pm Post subject: Re: std::vector von abgeleiteten template-Klassen |
|
|
On 27 Feb 2006 08:22:09 -0800, "CJ" <j.jungeblut (AT) gmx (DOT) de> wrote:
| Quote: | Hi!
Folgendes Problem:
Ich habe eine abstrakte Basisklasse, die eine Funktion beinhaltet, die
einen tamplate-Parameter besitzt.
z.B.:
template <class T
class base
{
public:
base(){ };
|
Der Strichpukt nach der geschweiften Klammer ist hier überflüssig. Nur
nach struct{}; class{}; union{}; oder enum{}; schreiben. Nach dem
Funktionsrumpf ist das zwar nicht direkt ein Fehler, unter Entwicklern
ist es doch etwas verpönt...
| Quote: | virtual void machwas(T* wert) = 0;
};
Diese Klasse leite ich jetzt ab, so dass ich verschiedene Kind-Klassen
mit unterschiedlichen Klassen für T besitze.
Also z.B.:
class child1 : public base<int
{
public:
child1() {};
void machwas(int* wert) {std::cout << *wert;};
|
Ohne Strichpunkt...
| Quote: | };
oder auch
class child2 : public base<char
etc.
Jetzt möchte ich eigentlich einen std::vector von allen instatiierten
Kind-Klassen anlegen.
Da diese aber unterschiedliche template-Werte haben, geht das
natürlich nicht.
Also habe ich folgendes probiert: std::vector von der gemeinsamen
Basisklasse.
std::vector<base> tVec;
Leider geht das auch nicht, da der template-Parameter ja unspezifiziert
ist.
Kann man überhaupt einen Vector von template-Klassen anlegen?
Wie geht das?
|
Es geht, wenn die template-Klasse selbst schon von einer
nicht-Template-Basisklasse erbt. Das hat aber nur dann Sinn, wenn
gemeinsame Funktionalität zwischen allen abgeleiteten Template-Klassen
besteht. Das heisst, dass man das Argument für machwas() nicht T*,
sondern eine Referenz oder Zeiger auf die "Urklasse" sein müsste, weil
in C++ kontravariante Argumenttypen nicht erlaubt sind.
Allerdings könnte man dem Konstruktor von der spezialisierten
Template-Instanzen ein T (oder T* oder T&) übergeben, das als
Member-Variable gehalten wird. Dann könnte die überladene machwas()
auf das Member zugreifen. Wobei die Funktion dann eigentlich gar kein
Argument braucht...und man keine "child"-Klassen braucht, sondern mit
explizite Spezialisierungen des jeweiligen Typs arbeitet.
Zum Beispiel:
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
class Urklasse
{
public:
virtual ~Urklasse() {}
virtual void machwas() = 0;
};
template <class T>
class base : public Urklasse
{
public:
base(T const &t) : t_(t) {}
void machwas() {
cout << "generische Version von base<T>:\tt_ == "
<< t_ << endl;
}
protected:
// eigentlich sollte man keine protected
// data-Members halten; na ja:
T t_;
private:
// versteckt, da nicht implementiert:
base();
};
template<>
void base<int>::machwas()
{ cout << "Spezialisierung von base<int>: \tt_ == " << t_ << endl; }
template<>
void base<char>::machwas()
{ cout << "Spezialisierung von base<char>: \tt_ == " << t_ << endl; }
template<>
void base<double>::machwas()
{ cout << "Spezialisierung von base<double>:\tt_ == " << t_ << endl; }
int main()
{
typedef vector<Urklasse*> CONTAINER;
typedef CONTAINER::iterator cont_it;
CONTAINER c;
c.push_back(new base<int>(64));
c.push_back(new base<char>(65));
c.push_back(new base<double>(65.1));
for(cont_it it = c.begin(); it != c.end(); ++it)
{
(*it)->machwas();
delete *it;
}
return 0;
};
--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Mon Feb 27, 2006 10:06 pm Post subject: Re: std::vector von abgeleiteten template-Klassen |
|
|
On Mon, 27 Feb 2006 22:12:00 +0100, Bob Hairgrove
<invalid (AT) bigfoot (DOT) com> wrote:
| Quote: | template <class T
class base : public Urklasse
{
public:
base(T const &t) : t_(t) {}
void machwas() {
cout << "generische Version von base<T>:\tt_ == "
t_ << endl;
}
protected:
// eigentlich sollte man keine protected
// data-Members halten; na ja:
T t_;
private:
// versteckt, da nicht implementiert:
base();
};
|
Ach ja ... da wir jetzt die Templates spezialisieren und keine
Kind-Klassen ableiten, kann jetzt t_ auch private sein. :)
Und machwas() evtl. auch in einer const-Version anbieten...
--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Olaf Krzikalla Guest
|
Posted: Tue Feb 28, 2006 3:06 pm Post subject: Re: std::vector von abgeleiteten template-Klassen |
|
|
Hi,
CJ wrote:
| Quote: | Folgendes Problem:
Ich habe eine abstrakte Basisklasse, die eine Funktion beinhaltet, die
einen tamplate-Parameter besitzt.
z.B.:
template <class T
class base
{
public:
base(){ };
virtual void machwas(T* wert) = 0;
};
Diese Klasse leite ich jetzt ab, so dass ich verschiedene Kind-Klassen
mit unterschiedlichen Klassen für T besitze.
Also z.B.:
class child1 : public base<int
{
public:
child1() {};
void machwas(int* wert) {std::cout << *wert;};
};
oder auch
class child2 : public base<char
etc.
Jetzt möchte ich eigentlich einen std::vector von allen instatiierten
Kind-Klassen anlegen.
Wofür genau brauchst Du das? Die einzelnen childs haben nichts gemeinsam |
-- nicht mal die Funktion 'machwas', da deren Signatur in jedem child
anders ist. Insofern stellt sich mir die Frage, wofür base überhaupt gut
sein soll. Hier wäre etwas mehr Kontext sehr hilfreich; ich vermute
nämlich, dass Dein Design nicht optimal zur Problemlösung ist. Auch ist
im Kontext der Templateprogrammierung nicht ganz eindeutig, was Du mit
'allen instatiierten Kind-Klassen' meinst. Ein Feld von Klassen kann man
in C++ nicht anlegen, also entweder ein Feld von je einem child1, child2
usw. oder ein Feld aller existierenden child1, child2 usw.
| Quote: | Also habe ich folgendes probiert: std::vector von der gemeinsamen
Basisklasse.
std::vector<base> tVec;
Leider geht das auch nicht, da der template-Parameter ja unspezifiziert
ist.
Kommt halt drauf an, wozu Du das brauchst. Du kannst z.B. den |
template-Parameter mitgeben:
template<class T>
void foo (std::vector< base<T> >& bar)
{
//...
}
| Quote: | Kann man überhaupt einen Vector von template-Klassen anlegen?
Nein. template-Klassen sind keine Klassen, sondern nur Klassentemplates. |
Einen std::vector instantiieren kann man nur mit Klassen.
MfG
Olaf Krzikalla
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|