PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Abstracte Klasse ? Klassen-Typ speichern????



nul
25-09-2007, 16:53
Es ist mal wieder soweit, ich muss die Weissheit des Forums um Hilfe bitten:

Also, ich habe eine Abstrakte Klasse namens AbstractData von der mehre Daten-Klassen erben. Diese Daten-Klassen implementieren alle eine statische Methode namens select(). (Die natuerlich in der Super-Klasse nicht definiert werden kann weil sie statisch ist)

Nun muesste ich in einer anderen Klasse jeweils einen Daten-Klassen-Typ speichern um die statische Methode aufzurufen. Eine Instanz der Daten-Klasse soll es nicht sein, da nur die statische Methode aufgerufen werden soll.

Ich hoffe ihr habt mich ueberhaupt verstanden :confused: .

Ist so etwas in C++ ueberhaupt moeglich? In Java wuerde ich das wahrscheinlich mit Class und dem ClassLoader implementieren, aber bin eben momentan bei einem C++ Projekt.

Vielleicht irgendwelche Tipps?

locus vivendi
25-09-2007, 18:03
Also, ich habe eine Abstrakte Klasse namens AbstractData von der mehre Daten-Klassen erben. Diese Daten-Klassen implementieren alle eine statische Methode namens select(). (Die natuerlich in der Super-Klasse nicht definiert werden kann weil sie statisch ist)

Nun muesste ich in einer anderen Klasse jeweils einen Daten-Klassen-Typ speichern um die statische Methode aufzurufen. Eine Instanz der Daten-Klasse soll es nicht sein, da nur die statische Methode aufgerufen werden soll.
Wenn ich das richtig verstanden habe, dann sollte es ausreichen einen Funktionszeiger zu speichern.

Statische Funktionen in Abstrakten Klassen kommen mir ein bisschen verdächtig vor, aber da ich deinen Code nicht kenne, gehe mich mal davon aus, das alles seine Berechtigung hat.

nul
25-09-2007, 19:24
Ok, habs mir schon gedacht dass das etwas unklar ist, also hier ein wenig Code:
Die abstrakte Klasse sieht so aus:

class AbstractData
{
public:
AbstractData();
AbstractData(const AbstractData& src);
virtual ~AbstractData() = 0;

AbstractData& operator=(const AbstractData& src);

virtual Glib::ustring get_name() = 0;

protected /* static */:
static mysqlpp::Query get_query();

protected:
void execute(mysqlpp::Query& query);
};
die wird von einigen anderen Klassen geerbt bzw. implementiert.

class DtSong : public AbstractData
{
public:
DtSong();
virtual ~DtSong();

DtSong(const DtSong& src);
DtSong operator=(const DtSong& src);

public:
// getters
guint get_id();
Glib::ustring get_name();
DtAudioCodec get_audiocodec();
DtLanguage get_language();
Glib::ustring get_description();

// setters
void set_id(guint id);
void set_name(Glib::ustring name);
void set_audiocodec(DtAudioCodec audiocodec);
void set_language(DtLanguage language);
void set_description(Glib::ustring description);

// database
void insert();
void update();
void remove();

public /* static */:
static DtSong select(guint id);
static std::list<DtSong> select();

protected:
DtSongMap convert2Map();

protected /* static */:
static DtSong convert2Dt(DtSongMap map);

protected:
guint dt_song_id;
Glib::ustring dt_song_name;
Glib::ustring dt_song_description;
DtAudioCodec dt_song_audiocodec;
DtLanguage dt_song_language;

private:
};
Die Methode

static std::list<DtSong> select();
wird von jeder von AbstractData erbenden Klassen implementiert.

Nun hab ich fuer ein Gtkmm-Combo Element folgendes Model erstellt:

class ComboModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
ComboModelColumns()
{ add(col_id); add(col_name); }

Gtk::TreeModelColumn<int> col_id;
Gtk::TreeModelColumn<Glib::ustring> col_name;
};
Hier soll nun noch ein Feld hinzukommen, mit dem man aben die Methode select() aufrufen kann.

Und zwar hol ich in einer Iterator-Schleife das gewaehlte element:

Gtk::TreeModel::Row row = *iter;
und moechte dann mit

std::list<AbstractData> datas = row[combobox_columns.col_data]::select();
oder aehnlich auf die select-Methode zugreifen.

locus vivendi
26-09-2007, 12:57
Die Methode

static std::list<DtSong> select();
wird von jeder von AbstractData erbenden Klassen implementiert.
Wird genau diese Funktion in jeder Klasse implementiert, oder ändert sich der Rückgabewert? DtSong ist ja hier der Typ der abgeleiteten Klasse. Wenn man jetzt eine Klasse XYZ hätte, die ebenfalls von AbstractData abgeleitet ist, würde diese Klasse dann ebenfalls "static std::list<DtSong> select()" haben, oder wäre es "static std::list<XYZ> select()"?


Und zwar hol ich in einer Iterator-Schleife das gewaehlte element:
Gtk::TreeModel::Row row = *iter;
und moechte dann mit

std::list<AbstractData> datas = row[combobox_columns.col_data]::select();
oder aehnlich auf die select-Methode zugreifen.
Welchen Typ hat "row[combobox_columns.col_data]"?

Kleiner Hinweise dazu noch: "std::list<AbstractData>" ist nicht erlaubt. Abstrakte Klassen dürfen nicht in Standardcontainer gesteckt werden. War möglicherweise nur ein Tippfehler, aber der Vollständigkeit halber sei es gesagt.

anda_skoa
26-09-2007, 14:38
Was spricht gehen ein


protected:
virtual std::list<AbtractData*> select(guint id) = 0;
virtual std::list<AbtractData*> select() = 0;

bzw. anders rum gefragt, was ist der exakte Anwendungsfall, warum du es bisher static hast.

Ciao,
_