2014-02-17 4 views
7

Я читал на основе концепции наследования в C++. У меня есть прилагаемый образец кода для всех. Я в основном спрашиваю, правильно ли это это понятие? Я новичок в этом, поэтому я просто откладываю то, что на уме. Любые комментарии/критические замечания приветствуются.Концептуальный полиморфизм

#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; 
} 

Заранее благодарен.

Blair

+3

Я не вижу ничего о понятиях там. Это просто нормальный полиморфизм на основе классов (независимо от собственного имени). (edit: oh, теперь я вижу, как это работает ... этот комментарий может быть совершенно неправильным) – immibis

+0

Примечание: «Концепции» сильно связаны программистами на C++ с предложением C++ 0x для проверки того, что типы переданы в качестве поддерживаемых параметров шаблона семантика; этот вопрос касается «концептуального полиморфизма», который является отличной идиомой для использования полиморфизма времени компиляции для создания полиморфного объекта во время выполнения. –

+0

Да, это то, о чем я говорю о Тони Д. Кине для комментариев. –

ответ

2

Несколько моментов:

  • Я не вижу особых оснований ставить drawable_concept или drawable_model внутри graphics_surface - вы просто предотвратить повторное то, что это потенциально полезным для других типов контейнеров ...

  • у вас есть какие-то проблемы const

    • draw, вероятно, следует const (и определение функций не должно сопровождаться точкой с запятой ;-)

    • drawable_model(T& item) должен принимать item от const ссылки

    • push_back(T& drawable) shoudl принять drawable от const ссылки

  • вы должны использовать make_shared для безопасности исключения

  • функциональность «Фабрика» будет, возможно, будет лучше выделился в отдельную функцию, а не похоронен внутри push_back

+0

Хорошие очки. Считаете ли вы, что это разумная реализация концептуального полиморфизма? –

+0

@BlairDavidson: базовая функциональность есть ... остальное сводится к тому, чтобы соответствовать вашим фактическим потребностям и должно появиться в стирке. Существуют примечательные вариации - например, создание полиморфных объектов во время выполнения, обертывающих только указатель на конкретный тип, вместо того, чтобы иметь конкретный объект, принадлежащий обертке, и * обязательно * выделение кучи. Оптимальное значение зависит от относительного времени жизни, независимо от того, пытаетесь ли вы минимизировать копирование данных (например, параллельный полиморфический доступ во время выполнения к объектам в общей памяти работает с указателем/оберткой). –

+0

Этот вопрос конкретно говорит о работе Шона Родитель: [Полиморфизм Runtime на основе концепции] (http://stlab.adobe.com/wiki/images/c/c9/Boost_poly.pdf). В примере используются частные концепции и классы моделей, хотя в нем явно не рассматриваются мотивации для этого выбора. – bames53

-2

Ваши triangle и square классы должны наследовать от graphics_surface::drawable_concept. Читайте перевод информации о virtual method tables.

См. Также wikipage on Concepts in C++.

+2

Не побеждает ли точка зрения основанный на концепции полиморфизм? –

1

Ваш подход здесь больше о стирании стилей, чем о программировании на основе концепции. Это расширение идеи, используемой boost :: any. Концепции представляют собой набор ограничений для типа, требуемого шаблоном класса или функции. STL имеет такие понятия, как ForwardIterator и InputIterator. Это ограничения, которые, как ожидается, будут истинны для параметров, переданных, например, для некоторых std-алгоритмов.

+1

К сожалению, «Понятия» за ваш ответ и предложение отложенного/убитого (?) C++ 0x совершенно иное, чем некоторые люди называли «концептуальный полиморфизм» - шаблонные заводы для захвата определенных операций над произвольными типами - о чем и идет речь. –

+0

Хм. Да, я согласен с вашей оценкой моего ответа. –

Смежные вопросы