abhängigkeit vermeiden
-
Angenommen ich habe eine Klasse in eine Library compiliert, die Klasse benutzt z.B. intern einen vector. Im header-File der Klasse ist das sichtbar, d.h. der anwender muss zwingend den vector-Header haben. Aber muss er das wirklich? Müsste nicht anstelle des vectors nur ein Typ gleicher grösse deklariert sein? Vorausgesetzt dass man über die klasse nicht direkt auf den vector zugreifen kann?
class blah { public: void SetElement(std::size_t index, double value); private: // kann man das verstecken? std::vector<double> m_data; };
-
Je nachdem kannst du auch einen Zeiger auf einen
std::vectorhaben und den<vector>-Header in der CPP-Datei erst einbinden.Die andere Möglichkeit wäre das Pimpl- oder Handle-Body-Idiom, das die Implementierung (und damit private Member) in einer separaten Klasse regelt.
-
Typen aus der Std-Lib würde ich nicht verstecken wollen müssen.
-
ok, danke. Das Idiom werde ich mir mal anschauen.
-
Im header-File der Klasse ist das sichtbar, d.h. der anwender muss zwingend den vector-Header haben.
Wie meinst du das? Der Benutzer deiner Klasse muss nichts über std::vector wissen. Er muss lediglich deinen Header inkludieren, welcher dann ja inkludieren kann, was er will. Du kannst im nachhinein immernoch etwas anderes benutzen und ganz von std::vector wegkommen. Das ist dem Benutzer schlussendlich doch egal. Er hat lediglich die Schnittstelle zu deiner Klasse und die interssiert ihn. Wie das implementiert ist spielt keine Rolle. Das Handle/Body Idiom ist dann ein weiterer Weg das ganze noch unabhängiger zu machen.
-
Dann geh anstatt von std::vector von boost::mutex aus, was vielleicht nicht jeder installiert hat.
-
drakon schrieb:
Im header-File der Klasse ist das sichtbar, d.h. der anwender muss zwingend den vector-Header haben.
Wie meinst du das? Der Benutzer deiner Klasse muss nichts über std::vector wissen. Er muss lediglich deinen Header inkludieren, welcher dann ja inkludieren kann, was er will. Du kannst im nachhinein immernoch etwas anderes benutzen und ganz von std::vector wegkommen. Das ist dem Benutzer schlussendlich doch egal. Er hat lediglich die Schnittstelle zu deiner Klasse und die interssiert ihn. Wie das implementiert ist spielt keine Rolle. Das Handle/Body Idiom ist dann ein weiterer Weg das ganze noch unabhängiger zu machen.
Es kann auch durchaus das Ziel sein, sich einige Abhängigkeiten zugunsten der Kompilierzeit zu sparen.
-
Stefan schrieb:
Dann geh anstatt von std::vector von boost::mutex aus, was vielleicht nicht jeder installiert hat.
OK, verstehe was du meinst. In dem Fall bist du mit dem pImpl wahrscheinlich wirklich am besten bedient.
Es kann auch durchaus das Ziel sein, sich einige Abhängigkeiten zugunsten der Kompilierzeit zu sparen.
Jup. Es ist immer gut die Abhängigkeiten so gering, wie möglich zu halten. Da stimme ich dir schon zu, aber die Frage hat für micht mit std::vector nicht viel Sinn gemacht.
- Jetzt ist es aber klar, was er gemeint hat mit dem "Vector-Header haben".
-
ok, mal blöd gefragt:
welchen Unterschied macht es für den Nutzer der Lib, wenn dort ein Header nicht in einem Header, sondern erst in der Implementierung eingebunden wurde?
Bzw. ändert sich generell was dadurch? (außer, dass man sich evtl. unnötige Kompilierabhängigkeiten spart, die bei einer als Binary ausgelieferten Lib ja eh hinfällig sind)
-
zwutz schrieb:
ok, mal blöd gefragt:
welchen Unterschied macht es für den Nutzer der Lib, wenn dort ein Header nicht in einem Header, sondern erst in der Implementierung eingebunden wurde?
Bzw. ändert sich generell was dadurch? (außer, dass man sich evtl. unnötige Kompilierabhängigkeiten spart, die bei einer als Binary ausgelieferten Lib ja eh hinfällig sind)Der Header wird in der mitkompiliert schon im vornherein und muss ihn dann nicht mitliefern, da im Header für den Benutzer lediglich eine Vorwärtsdeklaration steht und somit kein Wissen über die genaue Implementierung haben muss. (respektive der Header muss nicht auch noch von dem Benutzer kompiliert werden.)
-
drakon schrieb:
Der Header wird in der mitkompiliert schon im vornherein und muss ihn dann nicht mitliefern, da im Header für den Benutzer lediglich eine Vorwärtsdeklaration steht und somit kein Wissen über die genaue Implementierung haben muss. (respektive der Header muss nicht auch noch von dem Benutzer kompiliert werden.)
sollte man also einen externen Header verwenden, den man auf dem Zielsystem nicht voraussetzen kann (wie die boost-Geschichten), dann darf man den Header erst in der eigentlichen Implementierung einbinden und in der Header die entsprechende Forward-Declaration notieren?
gut zu wissen, danke
