sruct vs. class
-
Keine Angst, so schlimm wie sich der Titel liest ist die Frage nicht
Also: spricht eigentlich etwas dagegen, wenn ich nur eine Schnittstelle vorgeben will das in einer struct zu tun?
struct ISomething { virtual void HasToImpl() = 0; }; class Something : public ISomething : public SomeOtherThing { void HasToImpl(); };
Giebt es bei dieser Vorgehensweise( wenn nicht irgendwas grundlegendes dagegen spricht) irgendwas, was man beachten sollte?
-
Hi,
nö. Wenn du ne Klasse nimmst, machst du die Schnittstelle ja eh public, so dass es eigentlich völlig egal ist. Du sparst dir nur ein wenig Tipparbeit.
-
Das hat wohl auch MS erkannt.
objbase.h
#define interface struct
-
richtig:
class X { public: // was auch immer private: // was auch immer }; struct X { public: // was auch immer private: // was auch immer };
Sind vollkommen gleichwertig !
Aber ....
wer struct verwendet nur weil er nich public schreiben will, der frisst auch kleine kinder ... errr verwendet auch using namespace;
Konventionen machen das Leben fuer die programmierer einfacher ... und die wartbarkeit des Codes wird dadurch verbessert.
Fuer klassen ... also konstrukte die member daten gekapselt und methoden haben, sollte man prinzipiell class verwenden.
fuer strukturen im herkommlichen C-Sinne, die man in C++ meist nur noch braucht, um C-Schnittstellen zu anderen Biblios bedienen, sollte man auch struct verwenden ...Das MS interface mit struct definiert, akzeptier ich aus 2erlei gruenden ...
1. interface kommt vom midl compiler, und iss damit kein reines c++ :p Die schnittstellen selber sind auch nur C ...
2. nen interface iss per definition eine Sammlung von nur öffentlichen Methoden, eine Bedienungsanweisung ohne implementation sozusagen. Deshalb gehoeren private sachen prinzipiell nich in nen Interface rein ..
also eininterface { public: // was weiss ich };
Sähe per definition schon komisch aus ... da passt struct halt auch besser :p
@TheBigW
in deinem Beispiel ist dein Interface nich ganz koscher unter reinen c++ gesichtspunkten ....
dem fehlt der virtuelle destruktor, falls du mal das object ueber seine Schnittstellendef loeschen willst
WIllst du das nicht, musst es soweiso verhindern, in dem den destruktor nicht public machst, und dort dann noch struct zu verwenden ... poese pose :pMS deklariert fuer seine Interfaces prinzipiell auch keine virtuellen destruktoren ...
C++ technisch iss das naturlich nicht so ohne ... aber beim COM ist nen delete auf nen Schnittstellenzeiger soweiso nen programmtechnisches Inferno ....IMyInterface * ptest = new CMyInterfaceImpl; // ohje schon die erste Katastrophe .... delete ptest; // die endgueltige Katastrophe
Wenn es sich bei IMyInterface um ein richtiges COM-Interface handelt ...
Ciao ...
-
wer struct verwendet nur weil er nich public schreiben will
Neee, auch aus dem Grund das mir ja bei einer abstrakten KLasse in diesem Fall ja auch ein ctor aufs Auge gedrückt wird. Wenn ich dann exessiv aus verschiedenen Schnittstellendefinitionen meine endgültigen Objekte zusammenzimmer schleppe ich doch dann diesen Konstruktionsbalast (den ich nicht brauche) nicht mit, oder wie ist das beim Erben von einem struct?
Sobald ich Datenmember (die man auch initialisieren sollte) drinne hätte würde ich
natürlich 'ne abstrakte Klasse nehmen, aber wenn man die dann ähnlich verwenden würde, wäre man ja ruckzuck bei der "multiple inheritance" - Problematik mit dabei.[EDIT]
mhh, ein virtueller dtor in 'nem struct - irgendwie logisch. Bei Klassen ist mir das schon klar, das das auch bei structs funktioniert bisher noch nicht - Danke. Löschen über das Interace wäre dann schon ganz nett :).
-
TheBigW schrieb:
mhh, ein virtueller dtor in 'nem struct - irgendwie logisch. Bei Klassen ist mir das schon klar, das das auch bei structs funktioniert bisher noch nicht - Danke.
struct == class
der einzige unterschied ist der default zugriff, sonst nix.deshalb finde ich es auch ganz ok
struct twice { int operator()(int i) { return i*2; } };
zu schreiben.
-
Was dein Compiler dir automatisch mit aufs auge druckt, entscheidest du ganz allein damit, was du schon implementierst ...
ne class ohne jeglichen ctor ruft normal keinen kuenstlich generierten code auf, wenn du ne instanze mittels Parameter instanziierst, sondern kopiert einfach nur erbarmungslos den datenbereich, wie es ne struct auch machen wuerd ....
andersrum genau so ... ne struct mit mindestens einer virtuellen methode wird dir ne vtable generieren, genauso wie RTTI informationen, falls eingeschalten ...
@Shade
Ich finds nich ganz ok, aber naja, sind halt nur konventionen ...
*edit*
Ups, funktionsobjecte ... schreib ich meistens anders ... aber selbst in dem falle wuerd ich aber class und public nehmen ...Ciao ...
-
@RHBaum: wie genau arbeitet Deines mit einem std::transform zusammen?
-
RHBaum schrieb:
der code iss schon an den Haaren herbeigezogen oder ? Wer macht sowas ?
Ne, ist ein normaler functor. wuerde ich so verwenden, wenn ich zB alle elemente in einem container mal 2 nehmen will...
meine "version" zumindest saehe so aus !
class twice { public: static inline int operator()(int i) { return i*2; } };
Finde ich nicht schoen, bzw. wuerde das ja auch nicht gehen. aber warum static? dann nimmt man nen namespace und keine klasse
-
static geht eh nich bei operatoren oder ? das war ja der witz :p
Ich nehm bei der STL meist die nicht class version ... also ne template funktion oder so ...
im ersten ansatz seihts aber so auss, als wuerdest du nur um die funktion nutzen zu wollen, ne instanz benoetigen, was dir vielleicht nich jeder compiler wegoptimiert .... (deshalb lieber funktionen)
Wenn das teil nur als praedikate oder functor verwendest isses aber wurscht, weil ob funktionspointer oder instanz zu speichern, kommt fast aufs selbe raus
wie gesagt, ich find aber class mit public nicht wirklich haesslich ...
CIao ...
-
RHBaum schrieb:
im ersten ansatz seihts aber so auss, als wuerdest du nur um die funktion nutzen zu wollen, ne instanz benoetigen, was dir vielleicht nich jeder compiler wegoptimiert .... (deshalb lieber funktionen)
Ne, das siehst du falsch.
Die Klasse hat keine Member, sie ist also trivials zu optimieren.weiters bietet sich hier aber die moeglichkeit den op() zu inlinen, was bei funktionszeiger nur schwer moeglich, waehrend man es quasi gratis bei einem functor bekommt.
mal abgesehen davon, dass functoren einfach praktischer sind, weil sie problemlos noch einen state dazu bekommen koennen, wenn es denn noetig ist...