Warnung: Vererbung von Nicht-DLL-Schnittstelle
-
Ich benutze VS2010 und habe eine Klasse NonCopyable ohne __declspec. Scheint mir auch nicht nötig, da die einzige Methode (Defaultkonstruktor) inline ist.
Nun erhalte ich aber beim Ableiten von Klassen, die selbst mit__declspec(dllexport) gekennzeichnet sind, ständig folgende Warnung:
warning C4275: class 'NonCopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'XY' verwendet
Warum muss ich eine DLL-Schnittstelle haben, wenn die Methoden inline sind? Kann man die Warnung sinnvoll beheben oder soll ich sie einfach deaktivieren?
-
Steht alles in der Beschreibung:
http://msdn.microsoft.com/de-de/library/3tdb471s(v=vs.80).aspxFür noncopyable ist das natürlich kein Problem weil die Klasse keine Member hat.
Aber hätte sie welche, könnte eine abgeleitete KLasse in der EXE die DLL-Klasse eben nicht korrekt behandeln. Das ist der Hintergrund dieser Warnung.Ich würde nich versuchuen diese Mledung zu umgehen.
Du kannst das "noncopyable" auch anders erreichen
-
Martin Richter schrieb:
Für noncopyable ist das natürlich kein Problem weil die Klasse keine Member hat.
Aber hätte sie welche, könnte eine abgeleitete KLasse in der EXE die DLL-Klasse eben nicht korrekt behandeln. Das ist der Hintergrund dieser Warnung.Vielen Dank für die Erklärung. Schade, dass hier VS die Gefahrlosigkeit einer leeren Klasse nicht erkennt.
Martin Richter schrieb:
Ich würde nich versuchuen diese Mledung zu umgehen.
Du kannst das "noncopyable" auch anders erreichenJa, jedes Mal von Neuem Kopierkonstruktor und Zuweisungsoperator privat definieren. Tolle Lösung, genau das will ich mit NonCopyable ja vermeiden.
Kann ich die Warnung wenigstens lokal deaktivieren? Es scheint, als hätte
#pragma warning(push) #pragma warning(disable: 4275) class NonCopyable {...}; #pragma warning(pop)
keinen Einfluss, da das Ableiten an anderer Stelle geschieht. Gibt es keinen anderen Weg, als die Warnung global abzuschalten?
-
Nein. Du kannst auch eine gemeinsame entsprechende Klasse bauen, die Du exportierst.
-
mMn. spricht auch nix dagegen die Klasse NonCopyable einfach zu exportieren.
Es ist zwar nicht nötig, schadet aber auch nicht, und dann sollte der Compiler Ruhe geben.
-
Ich verwende die Klasse in einer Header-Only-Library. Da will ich möglichst vermeiden, dass der Benutzer etwas konfigurieren muss.
Wäre folgendes ein gangbarer Weg, um trotzdem portabel zu bleiben? Oder gibts da Probleme, wenn man gar keine DLL erstellen möchte?
#if (defined(_WIN32) || defined(__WIN32__)) #define MY_API __declspec(dllexport) #else #define MY_API #endif class MY_API NonCopyable { ... };
-
Grundsätzlich immer
__declspec(dllexport)
ist nicht der richtige Weg.__declspec(dllexport)
sollte nur beim Bauen der DLL verwendet werden, beim Bauen von anderem Code der diese DLL verwendet musst du entsprechend__declspec(dllimport)
verwenden.Spendiere der DLL doch ihre eigene "MyDllNonCopyable" Klasse. Dann ist die unabhängig von deiner Header-Only Lib und alles ist gut.