2014-02-17 18 views
7

Ich habe auf Concept-basierte Vererbung in C++ gelesen. Ich habe ein Codebeispiel für alle beigefügt. Ich frage im Grunde, ob dies eine korrekte Umsetzung des Konzepts ist? Ich bin neu in diesem Bereich, also lege ich nur nieder, was ich denke. Kommentare/Kritik sind willkommen.Konzeptbasierter Polymorphismus

#include "stdafx.h" 
#include <memory> 
#include <vector> 
#include <algorithm> 
#include <iostream> 

using namespace std; 

struct Point{ 
    int x; 
    int y; 
}; 

class graphics_surface{ 

    class drawable_concept{ 
    public: 
     virtual void draw(Point const& coordinate) {}; 
     virtual ~drawable_concept() {}; 
    }; 

    template<class T> 
    class drawable_model : public drawable_concept{ 
    public: 
     drawable_model(T& item) : item_(item){} 
     void draw(Point const& coordinate){ 
      item_.draw(coordinate); 
     } 
     ~drawable_model(){} 
    private: 
     T item_; 
    }; 

public: 

    template<class T> 
    void push_back(T& drawable){ 
     v_.push_back(shared_ptr<drawable_concept>(new drawable_model<T>(drawable))); 
    } 

    void draw(Point const& coordinate) { 
     for_each(v_.begin(), v_.end(), [&](shared_ptr<drawable_concept>& concept){ 
      concept->draw(coordinate); 
     }); 
    } 

private: 
    vector<shared_ptr<drawable_concept>> v_; 
}; 

struct triangle{ 
    void draw(Point const& p){ 
     cout << "Triangle: " << p.x << "," << p.y << endl; 
    } 
}; 

struct square{ 
    void draw(Point const& p){ 
     cout << "Sqaure: " << p.x << "," << p.y << endl; 
    } 
}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 

    Point p; 
    p.x = 1; 
    p.y = 2; 

    graphics_surface surface; 
    surface.push_back(triangle()); 

    surface.draw(p); 

    return 0; 
} 

Vielen Dank im Voraus.

Blair

+3

Ich sehe nichts über Konzepte in nicht da. Es ist nur normale klassenbasierte Polymorphie (was auch immer der richtige Name dafür ist). (edit: oh, jetzt sehe ich, wie das funktioniert ... dieser Kommentar könnte komplett falsch sein) – immibis

+0

Hinweis: "Konzepte" ist stark von C++ - Programmierern mit dem C++ 0x-Vorschlag für die Überprüfung, dass Typen als Template-Parameter übergeben unterstützt spezifisch zugeordnet Semantik; Diese Frage bezieht sich auf "Konzeptbasierter Polymorphismus", der ein unterschiedliches Idiom für die Verwendung von Kompilierungszeitpolymorphismus zum Erstellen eines polymorphen Laufzeitobjekts darstellt. –

+0

Ja, darüber spreche ich über Tony D. Keen für Kommentare. –

Antwort

2

Einige Punkte:

  • Ich habe keinen guten Grund sehen drawable_concept oder drawable_model innerhalb graphics_surface setzen - man muss nur die Wiederverwendung von etwas verhindern, die in anderen Containertypen potentiell nützlich ist ...

  • Sie einige const Probleme haben

    • draw sollte wahrscheinlich sein const (und Funktionsdefinitionen sollten nicht durch Semikolons ;-)

    • drawable_model(T& item) sollte item von const nehmen Bezug

    • push_back(T& drawable) shoudl nehmen drawable von const

  • Referenz folgen Verwenden Sie für die Ausnahmesicherheit make_shared

  • die „Fabrik“ Funktionalität wäre wohl besser in eine separate Funktion getrennt werden, anstatt begraben innen push_back

+0

Gute Punkte. Denken Sie, dass dies eine vernünftige Umsetzung des Konzept-basierten Polymorphismus ist? –

+0

@BlairDavidson: die Grundfunktionalität ist da ... der Rest kommt auf Ihre tatsächliche Verwendung (n) und sollte in der Wäsche herauskommen. Es gibt bemerkenswerte Varianten - zum Beispiel das Erzeugen von polymorphen Laufzeit-Objekten, die nur einen Zeiger auf den konkreten Typ umhüllen, anstatt das konkrete Objekt, dem der Wrapper und der * notwendigerweise * zugeordnete Heap zugeordnet sind. Was optimal ist, hängt von den relativen Lebensdauern ab, unabhängig davon, ob Sie versuchen, das Kopieren von Daten zu minimieren (z. B. gleichzeitige polymorphe Zugriffe auf Objekte im Shared-Memory-Modus mit dem Zeiger/Wrapper). –

+0

Diese Frage bezieht sich speziell auf die Arbeit von Sean Parent: [Konzeptbasierte Laufzeitpolymorphie] (http://stlab.adobe.com/wiki/images/c/c9/Boost_poly.pdf). In diesem Beispiel werden private Konzept- und Modellklassen verwendet, die Motivation für diese Auswahl wird jedoch nicht explizit behandelt. – bames53

-2

Ihre triangle und square Klassen sollten von graphics_surface::drawable_concept erben. Lesen Sie über virtual method tables.

Siehe auch wikipage auf Concepts in C++.

+2

Widerspricht das nicht dem Konzeptpolymorphismus? –

1

Hier geht es eher um Typ-Löschen als um Konzept-basierte Programmierung. Es ist eine Erweiterung der Idee von boost :: any. Konzepte sind eine Reihe von Einschränkungen für einen Typ, der für eine Klassen- oder Funktionsvorlage erforderlich ist. Die STL hat Konzepte wie ForwardIterator und InputIterator. Dies sind Einschränkungen, von denen erwartet wird, dass sie zum Beispiel für Parameter gelten, die an einige Standardalgorithmen übergeben werden.

+1

Leider sind "Konzepte" pro Antwort und das verzögerte/gekillte (?) C++ 0x-Angebot etwas völlig anderes als das, was manche Leute "Konzeptbasierter Polymorphismus" nennen - Template-Fabriken zur Erfassung bestimmter Operationen auf beliebigen Typen - darum geht es in der Frage. –

+0

Hmm. Ja, ich stimme Ihrer Einschätzung meiner Antwort zu. –