Zugriff auf Methoden abgeleiteter Klassen die allerdings nicht in der Basisklasse definiert sind mit Basisklassenzeiger
-
fluxy schrieb:
sorry aber das ist falsch.
Ich muss einen Zugriff auf meine XComBase Zeiger haben. Das Problem ist das die Anwendung nicht jeden Pointer selbst speichern soll, sondern das der Manager übernimmt. Der Manager gibt dabei beim einfügen in die Map einen key zurück, über den das Element identifiziert werden kann. Um die Instanz zu bekommen, wird genau dieser Schüssel wieder angegeben.
Soweit ich weiss, ist das mit std::vector nicht möglich. Dort müsste ich meine Instanz erst suchen.
du fügst die Daten so in die Map ein:
static int counter = 0; ... plgStack.insert(make_pair (counter, ptr_base)); *mglog << "Neues Element in map eingefügt mit ID " << counter << endl; counter++;
du fügst "counter" als der Schlüssel ein und bekomst die folgende Datei:
plgStack[0] == ptr_base1 plgStack[1] == ptr_base2 ... plgStack[n] == ptr_baseN
wenn du so schreibst:
std::vector<"typeof(ptr_base)"> plgStack; ... plgStack.push_back(ptr_base);
kannst du deine Datei genauso bekommen:
plgStack[0] == ptr_base1 plgStack[1] == ptr_base2 ... plgStack[n] == ptr_baseN
oder hab ich was wieder falsch verstanden?
-
fluxy schrieb:
mape_pair: wie das aussieht weiss ich nicht, dass ist eine C++ Funktion, ich glaube der ist in map.h definiert. .
map.h gibt es nicht, alle Header der Standardbibliothek haben keine Endung. std::pair und dazugehörige std::make_pair befinden sich in <utility>.
std::make_pair ist dazu da, die explizite Angabe von Template-Argumenten zu umgehen, das heißt die Typen werden aus der Parameterliste hergeleitet. Auf diese Weise funktionieren viele andere Algorithmen des Standardbibliothek, siehe <functional>
-
well done Shio.
Aber was mache ich da denn nun falsch?
-
mit dem Vector:
ja, ist komplett richtig, aber: Eine Map ist so organisiert dass ich den Schlüssel direkt finde. Bei einem Vector müsste ich wissen, das wievielte Element es ist, welches eiengefügt wurde weil es nur ein Array ist. Das Arrayelement ist aber keine wirklich keyangabe, das ist der Unterschied.
-
fluxy schrieb:
mit dem Vector:
ja, ist komplett richtig, aber: Eine Map ist so organisiert dass ich den Schlüssel direkt finde. Bei einem Vector müsste ich wissen, das wievielte Element es ist, welches eiengefügt wurde weil es nur ein Array ist. Das Arrayelement ist aber keine wirklich keyangabe, das ist der Unterschied.
Das Arrayelement ist in deinem Fall wirklich Keyangabe.
-
fluxy schrieb:
well done Shio.
Aber was mache ich da denn nun falsch?
sieht deine declaration von plgStack genauso aus?
std::map<int, XComBase*> plgStack?
-
ja genau so...
-
fluxy schrieb:
ja genau so...
mist
und so:
//plgStack.insert(make_pair (counter, ptr_base)); plgStack[counter] = ptr_base;
?
-
wieso sagtest du misst?
das plgStack[counter] = .... ist schwachsinn, weil ich meine Plugins nicht numerisch halten will, auch wenn die variable counter darauf schliessen lässt. Ich will da dynamischer bleiben.
-
fluxy schrieb:
das plgStack[counter] = .... ist schwachsinn, weil ich meine Plugins nicht numerisch halten will, auch wenn die variable counter darauf schliessen lässt. Ich will da dynamischer bleiben.
map::operator[] Inserts an element into a map with a specified key value.
Type& operator[](
const Key& _Key
);Parameter
_Key
The key value of the element that is to be inserted.
Return Value
A reference to the data value of the inserted element.Remarks
If the argument key value is not found, then it is inserted along with the default value of the data type.operator[] may be used to insert elements into a map m using m[_Key] = DataValue; where DataValue is the value of the mapped_type of the element with a key value of _Key.
When using operator[] to insert elements, the returned reference does not indicate whether an insertion is changing a pre-existing element or creating a new one. The member functions find and insert can be used to determine whether an element with a specified key is already present before an insertion.
-
nagut dann gibt es eben die Möglichkeit, so darüber zuzugreifen.... aber wieso klappt meins denn nicht?
-
fluxy schrieb:
nagut dann gibt es eben die Möglichkeit, so darüber zuzugreifen.... aber wieso klappt meins denn nicht?
klappt es mit map::operator[] oder auch nich?
-
nein das klappt genausowenig.
Er schmiert ab und geht in utility.h dort herein:
template<class _Other1, class _Other2> pair(const pair<_Other1, _Other2>& _Right) : first(_Right.first), second(_Right.second) { // construct from compatible pair }
-
kann es sein, dass einer der beiden werte beim kopieren ne exception werfen können?
-
fluxy schrieb:
nein das klappt genausowenig.
Er schmiert ab und geht in utility.h dort herein:
template<class _Other1, class _Other2> pair(const pair<_Other1, _Other2>& _Right) : first(_Right.first), second(_Right.second) { // construct from compatible pair }
könntest du eine vollständige Teil von deiner Code zeigen, die ich compilieren kann und wo ich sehen kann, dass map.insert abschmiert?
-
ja klar warte ich mache dir was fertig
-
entschuldige.... aber irgendwie schmiert mein Beispiel nicht ab.... Ich versteh es nicht....
Ich habe es überprüft....
Hier mal die Werte zum Zeitpunkt des Einfügens:
gplg 0x10001770 XExport(HINSTANCE__ *, XComBase * *, XGuiMessageSystem
unsigned long (HINSTANCE__ *, XComGuiBase * *, XGuiMessageSystem )
+ ptr_base 0x00364b68 {hWindow=0xabababab {unused=??? } m_hTree=0xfeeefeee {unused=??? } b_keys=0x00364b78 ...} XComGuiBase *
counter 0 int
hDll 0x10000000 {unused=9460301 } HINSTANCE__ *
plgID 1 unsigned longthis 0x00320c10 {plgStack={size=0} mglog=0x00321100 {file=0x003211a8 {_Filebuffer={_Pcvt=0x00000000 _State0=0 _Mychar='Í' ...} } } ptr_pref=0x003239e8 {ptr_name=0x004570d0 "marco" ptr_register=0x004570c8 "test" posx=10 ...} } XComManager * const
-
fluxy schrieb:
entschuldige.... aber irgendwie schmiert mein Beispiel nicht ab.... Ich versteh es nicht....
Ich habe es überprüft....
ich denke, du hast irgendwo falsch mit memory gearbeitet. arbeite lieber mit std::auto_ptr && boost::shared_ptr anstatt pointers. Das soll viele Problemen einfach lösen.
Hier mal die Werte zum Zeitpunkt des Einfügens:
...ich bin keinen Debuger
, ich brauche quelle C++ code
-
Sorry ..... hier ist er (hoffe is net zu viel...):
#ifndef INTERFACE_H #define INTERFACE_H typedef struct XColor { float fl_red; float fl_green; float fl_blue; }; typedef struct XGuiPrefences { char* ptr_name; //name displayed in the window names area char* ptr_register; //name of window with which window is registered int posx; //first coordinate of upper left corner int posy; //second coordinate of upper left corner int width; //windows width int height; //widnows height XColor fl_brcol; //window background float fl_Alpha; //alpha channel }; class XComBase { public: virtual unsigned long executeCommand (void) = 0; virtual unsigned long registerPlugin (void) = 0; virtual unsigned long unregisterPlugin (void) = 0; virtual void* getPluginMethods (void) = 0; private: protected: }; class XComGuiBase : virtual public XComBase { public: virtual int xCreate (XGuiPrefences* ptr_render, int menu) = 0; virtual int xMain (XGuiPrefences* ptr_render) = 0; virtual bool showConsole (bool is_shown) = 0; virtual void InfoBox (char* message, char* title) = 0; virtual void ErrorBox (char* message, char* title) = 0; virtual int addButton (int x, int y, int cx, int cy, int id, char* name) = 0; virtual void setKey (int key, bool state) = 0; virtual bool InitCommonControls (void) = 0; virtual bool CreateTreeview (int x, int y, int cx, int cy, int id) = 0; virtual int AddElementToTreeview (int nLocation, char* elem, bool sorted) = 0; private: protected: }; class XGuiMessageSystem { public: virtual int Event_WindowCreate (void) {return 0;} virtual int Event_MouseMoved (void) { return 0; } virtual int Event_Repaint (void) { return 0; } virtual int Event_Resize (void) {return 0; } virtual int Event_MouseClicked (int x, int y) {return 0; } virtual int Event_MouseClickedRight (int x, int y) { return 0; } virtual int Event_Clicked (int widget) { return 0; } virtual int Event_MouseClickedSecundary (int x, int y) { return 0;} virtual int Event_Create (void) { return 0; } virtual int Event_KeyPressed (int key) { return 0; } virtual int Event_KeyUnpressed (int key) { return 0; } virtual int Event_Background (void) { return 0; } private: protected: }; #endif #ifndef X_COM_MANAGER #define X_COM_MANAGER #include <vector> #include <iostream> #include "XInterface.h" #include "XGen.h" #include <log.h> #include <windows.h> #include <vector> #include <map> #include <direct.h> using namespace std; class XComManager { public: XComManager (XGuiPrefences* ptr_pref); virtual ~XComManager (void); virtual unsigned long registerPlugin (unsigned long plgID, XComGuiBase* ptr_base, XGuiMessageSystem* ptr_message); virtual unsigned long startPlugin (void); virtual unsigned long stopPlugin (void); virtual unsigned long releasePlugin (void); virtual XComGuiBase* GetPlugin (int pos); private: std::map<int, XComBase*> plgStack; LOG* mglog; XGuiPrefences* ptr_pref; protected: }; /* function pointers */ extern "C" typedef unsigned long (*GUI_PLG) (HINSTANCE hdll, XComGuiBase**, XGuiMessageSystem*); #endif unsigned long XComManager::registerPlugin (unsigned long plgID, XComGuiBase* ptr_base, XGuiMessageSystem* ptr_message) { HMODULE hDll = (HMODULE) NULL; char* dllname = new char [100]; static int counter = 0; // GUI - Plugin laden if (plgID == PLG_GUI) { *mglog << "Plugin erkannt auf PLG_GUI" << endl; #ifdef WIN32 strcpy ((char*)dllname, (char*)"dll"); strcat ((char*)dllname, (char*)"\\XWin32.dll"); *mglog << "Betriebsystem erkannt auf >>WINDOWS<<" << endl; if (!(hDll = LoadLibraryEx (dllname, NULL, 0))) { *mglog << "Error binding Dll to application's address space" << endl; } /* Zeiger auf die richtige Klasse initialisieren und dann im Pluginvektor abspeichern, damit die Anwendung darauf zugreifen kann */ GUI_PLG gplg = NULL; gplg = (GUI_PLG) GetProcAddress (hDll, "XExport"); gplg (hDll, &ptr_base, ptr_message); //plgStack[counter] = ptr_base; plgStack.insert (std::pair<int, XComGuiBase*>(counter, ptr_base)); *mglog << "Neues Element in map eingefügt mit ID " << counter << endl; counter++; #else //Lade Linuxpluigin #endif } // Render - Plugin laden else if (plgID == PLG_RENDER) { } return 0; }
-
fluxy schrieb:
Sorry ..... hier ist er (hoffe is net zu viel...):
zeig mir wie du XComManager benutzst, wie du "registerPlugin" rufst und noch die folgenden Methoden:
XComManager::XComManager (XGuiPrefences* ptr_pref);
XComManager::~XComManager();