Можем ли мы превратить такую ​​структуру в типизированный класс / функцию? - PullRequest
1 голос
/ 30 января 2011

Так что в структуре, подобной

struct RenderCastedDataFunctor
{
    simpleRendererGraphElement* obj_;

    RenderCastedDataFunctor(simpleRendererGraphElement* obj)
        : obj_(obj) { }

    void operator()(char* castedChar, int castedCharLength)
    {
        obj_->renderCastedData(castedChar, castedCharLength);
    }
};

, мы можем превратить simpleRendererGraphElement * в абстрактный тип и сделать его имя функции, которое мы используем в структуре (renderCastedData) abstract тоже?

Итак, у меня естьфункция внутри charGenerator класс

template <typename Function>
void AddSubscriberToGeneratedData(Function f)

Я хочу передать ей функции из различных классов type void (differentClass::*)(char*, int)

С этой структурой внутри некоторого simpleRendererGraphElement я могу подписаться на функцию с именем renderCastedDataк данным с charGenerator->AddSubscriberToGeneratedData(RenderCastedDataFunctor(this)); Я хочу иметь возможность передавать абстрактную функцию класса, которая принимает char* и int до AddSubscriberToGeneratedData.Как это сделать?

1 Ответ

2 голосов
/ 30 января 2011

мы можем повернуть simpleRendererGraphElement * в абстрактный тип и сделать его функцию имя, которое мы используем в структуре (renderCastedData) абстрактный тоже?

Очень очень хорошая идея. Ты должен сделать это. Сделайте класс абстрактным, сделав его функции virtual, а затем определите конкретный класс (производный от этого абстрактного класса), который реализует виртуальные функции. Это был бы лучший дизайн!

А в остальном все уже в порядке. Вам не нужно ничего делать, поскольку вы делаете это:

AddSubscriberToGeneratedData(RenderCastedDataFunctor(this));

Полагаю, здесь this представляет указатель на экземпляр конкретного класса. Если так, то это должно сработать!


EDIT:

Я понимаю, насколько хороша эта идея, но Я не понимаю, как это реализовать. тот вот почему я спрашиваю.

Хорошо. Вот пример:

class AbstractGraphElement
{
  public:
    virtual void RenderCastedData(char* castedChar, int castedCharLength) = 0;
};

Это ваш абстрактный класс, а RenderCastedData - чисто виртуальная функция. Теперь вам нужно определить конкретный класс, который должен определить функцию RenderCastedData. Итак, вот оно:

class SimpleGraphElement : public AbstractGraphElement
{
  public:
    virtual void RenderCastedData(char* castedChar, int castedCharLength)
    {
        //function body - define it yourself
    }
};

Готово!

Теперь вам нужно сделать следующее. Изменить RenderCastedDataFunctor следующим образом:

struct RenderCastedDataFunctor
{
    AbstractGraphElement* m_graphElement;

    RenderCastedDataFunctor(AbstractGraphElement* graphElement)
        : m_graphElement(graphElement) { }

    void operator()(char* castedChar, int castedCharLength)
    {
        m_graphElement->RenderCastedData(castedChar, castedCharLength);
    }
};

Затем добавьте подписчика,

AbstractGraphElement *pGraphElement = new SimpleGraphElement();
AddSubscriberToGeneratedData(RenderCastedDataFunctor(pGraphElement));

Я думаю, это дало вам некоторое представление, верно? Важный момент: используйте указатель типа AbstractGraphElement, но инициализируйте этот указатель с SimpleGraphElement. Я думаю, вы должны прочитать о виртуальных функциях и полиморфизме времени выполнения. Это очень тебе поможет.

...