Ist es in Ordnung, die Implementierung von STL-Containern zu erben, anstatt sie zu delegieren?C++

Programme in C++. Entwicklerforum
Guest
 Ist es in Ordnung, die Implementierung von STL-Containern zu erben, anstatt sie zu delegieren?

Post by Guest »

Ich habe eine Klasse, die std::vector anpasst, um einen Container mit domänenspezifischen Objekten zu modellieren. Ich möchte dem Benutzer den größten Teil der std::vector-API zugänglich machen, damit er vertraute Methoden (Größe, Löschen, At usw.) und Standardalgorithmen für den Container verwenden kann. Dies scheint für mich ein wiederkehrendes Muster in meinen Designs zu sein:

Code: Select all

class MyContainer : public std::vector
{
public:
// Redeclare all container traits: value_type, iterator, etc...

// Domain-specific constructors
// (more useful to the user than std::vector ones...)

// Add a few domain-specific helper methods...

// Perhaps modify or hide a few methods (domain-related)
};
Ich bin mir der Praxis bewusst, bei der Wiederverwendung einer Klasse für die Implementierung die Komposition der Vererbung vorzuziehen – aber es muss eine Grenze geben! Wenn ich alles an std::vector delegieren würde, gäbe es (nach meiner Zählung) 32 Weiterleitungsfunktionen!

Meine Fragen sind also... Ist das wirklich so? Ist es in solchen Fällen schlecht, die Implementierung zu erben? Was sind die Risiken? Gibt es eine sicherere Möglichkeit, dies umzusetzen, ohne so viel tippen zu müssen? Bin ich ein Ketzer, weil ich die Implementierungsvererbung verwende? :)

Bearbeiten:

Wie wäre es damit, klarzustellen, dass der Benutzer dies tun sollte? Verwenden Sie MyContainer nicht über einen std::vector-Zeiger:

Code: Select all

// non_api_header_file.h
namespace detail
{
typedef std::vector MyObjectBase;
}

// api_header_file.h
class MyContainer : public detail::MyObjectBase
{
// ...
};
Die Boost-Bibliotheken scheinen dieses Zeug ständig zu machen.

Edit 2:

Einer der Vorschläge war, kostenlose Funktionen zu nutzen. Ich zeige es hier als Pseudocode:

Code: Select all

typedef std::vector MyCollection;
void specialCollectionInitializer(MyCollection& c, arguments...);
result specialCollectionFunction(const MyCollection& c);
etc...
Eine eher OO-artige Vorgehensweise:

Code: Select all

typedef std::vector MyCollection;
class MyCollectionWrapper
{
public:
// Constructor
MyCollectionWrapper(arguments...) {construct coll_}

// Access collection directly
MyCollection& collection() {return coll_;}
const MyCollection& collection() const {return coll_;}

// Special domain-related methods
result mySpecialMethod(arguments...);

private:
MyCollection coll_;
// Other domain-specific member variables used
// in conjunction with the collection.
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post