C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

std::vector von abgeleiteten template-Klassen

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
CJ
Guest





PostPosted: Mon Feb 27, 2006 8:06 pm    Post subject: std::vector von abgeleiteten template-Klassen Reply with 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(){ };
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





PostPosted: Mon Feb 27, 2006 10:06 pm    Post subject: Re: std::vector von abgeleiteten template-Klassen Reply with quote



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





PostPosted: Mon Feb 27, 2006 10:06 pm    Post subject: Re: std::vector von abgeleiteten template-Klassen Reply with quote



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





PostPosted: Tue Feb 28, 2006 3:06 pm    Post subject: Re: std::vector von abgeleiteten template-Klassen Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.