Static member in DLL

Ryu1991

Erfahrenes Mitglied
Hey,
ich habe folgendes Problem. Ich habe eine Klasse in einer DLL die einen Static member hat, hier kurz mal die Definition:

C++:
enum DisplayObjectType
{
	Room, NPC, Item
};


class DLL DisplayObject
{
	public:
		DisplayObject(QString Id, DisplayObjectType dispType);
		~DisplayObject();

		QString getImageId();
		QString getIdentifier();
		QString getDescriptionId();
		QString getDisplayName();

	protected:
		QString ImageId;
		QString DescriptionId;
		QString DisplayName;

	private:
		QString Identifier;
		
		static std::map<DisplayObjectType, std::list<QString>> Instances;
};

std::map<DisplayObjectType, std::list<QString>> DisplayObject::Instances;

und kriege beim Compilieren die Warnung :
Code:
 displayobject.h(37): warning C4273: 'Instances': Inkonsistente DLL-Bindung.
was sich auf Zeile der Definition von Instances bezieht. Wenn ich die Warunung ausschalte
(per #pragma warning( disable: 4273 ) wird der Fehler :
Code:
 displayobject.h(37): error C2491: 'DisplayObject::Instances': Definition von Statisches Datenmember für dllimport nicht zulässig
draus.

Wenn ich die Definition in das .cpp file packe, lässt sich der spaß zwar compilieren, aber die anwendung stürzt direk beim Starten ab.
Ganz weglassen geht natürlich auch nicht, weil dann eine Beschwerde über eine fehlende Definition kommt.
Ich bin hier inzwischen ziemlich am Haareraufen, weil ich keine Lösung finde.
Übrigens treten sowohl der Fehler als auch die Warnung beim Compilieren der Anwendung auf, und nicht beim compilieren der Bibliothek.
Was mich dabei so verwirrt, ist, dass genau das gleiche in einer andere klasse super funktioniert.

Und noch eine Andere Frage: Ich brauche die Map um kontrollieren zu können, dass keines der von DisplayObject in zukunft erbenden Objekte der selben Klasse die gleiche Id haben können. Was mich allerdings stört, ist dass ich jedesmal, wenn ich einen neuen Typ einführen werde später, ich auch das Enum erweitern muss, und das finde ich unelegant. Fällt euch da vielleicht eine bessere Lösung ein?
 
Hi.

Die Definition des statischen Members darf nicht in die Headerdatei.

Mit welcher Meldung stürzt die Anwendung dann beim Starten ab?

Vermutlich hat der Absturz eine andere Ursache.
 
Hey,
vielen dank für deinen Hinweis. Dank ihm habe ich den Fehler gefunden.
Ich hatte im Konstruktor von DisplayObject auf ein nicht-existentes element von Instances via map::at() zugegriffen, weil ich erst mit Pointern experimentiert habe, um den Fehler loszuwerden, und nicht wusste , ob der [] opperator funktioniert, wenn nen Map pointer verwende.
Und dann habe ich aus -> nur noch nen . gemacht, statt wieder den opperator zu benutzen, weil ich davon ausgegangen bin, dass die ind er Funktion identisch sind. Dummer Fehler ...

Eine Frage hätte ich allerdings noch. Wenn die Definition nicht in die Header Datei darf, warum funktioniert dann dieser Header 1a?

C++:
#ifndef SINGLETON_H
#define SINGLETON_H

#include "../../definitions.h"

template<class T>
class DLL Singleton
{
	public:
		static T *getInstance()
			{
				if(Instance == nullptr)
					Instance = new T;

				return Instance;
			}


	protected:
		Singleton(){}

	private:
		static T *Instance;
};

template<class T> T *Singleton<T>::Instance = nullptr;

#endif
 
Eine Frage hätte ich allerdings noch. Wenn die Definition nicht in die Header Datei darf, warum funktioniert dann dieser Header 1a?
Templates sind noch kein Code. Es ist nur eine "Schablone" um Code zu generieren. Insbesondere erzeugt Zeile 26 noch keine Variable; das geschieht erst bei der Instantiierung.

Um ein Template zu instantiieren muß der Template-Code in der entsprechenden Code Einheit (durch include) verfügbar sein (wie sollte der Compiler ansonsten den "echten" Code generieren können).
 
Zurück