Как удалить ненужные функции из интерфейса - PullRequest
5 голосов
/ 21 октября 2010

У меня есть интерфейс класса MyFunction. В этом классе есть три функции со следующими сигнатурами:

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;

Теперь любая реализация MyFunction должна будет реализовать только одну из этих функций, в зависимости от того, какой тип значения она должна вернуть. Но мне придется реализовать все 3 функции, даже если две другие функции будут такими:

virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}

, который выглядит не очень хорошо. Или я могу объявить все три функции, как это в интерфейсе:

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}

Что тоже выглядит некрасиво. Что менее уродливо из этих двух? Или есть лучший способ сделать это?

EDIT:

По методу Д. Крюгера:

#include <iostream>

using namespace std;

class Base
{
    public:
        template<typename T>
            void F(T){cout << "Type T" << endl;}
};

class Imp : public Base
{
    public:
        template<int>
            void F(int){cout << "Type int" << endl;}
};

int main(int argc, char** argv)
{
    Base* pB;
    Imp oI;
    pB = &oI;

    pB->F(1);
}

Похоже, специализация не распространяется на классы, хотя и производные. Поскольку функции шаблонов не могут быть виртуальными, похоже, это безнадежная ситуация.

Ответы [ 3 ]

3 голосов
/ 21 октября 2010

Поскольку существует взаимно-однозначное соответствие между типами, используемыми в Eval (), и числом реализаций, функция-член шаблона должна работать.

class MyFunction {

    template <class T>
    bool Eval(T& returnVal, size_t szArgumentCount, list<Param> lParameterList) 
        { return false; }
};

Затем реализуйте специализации для типовэто не должно возвращать false.

Для этого требуется только одна универсальная реализация для возврата false и три реализации, которые понадобятся в любом случае.

2 голосов
/ 21 октября 2010

Это признак того, что ваш дизайн интерфейса может нуждаться в рефакторинге, когда классам, реализующим интерфейс, не нужно все количество методов в нем. Возможно, вы могли бы разделить этот интерфейс на 3 интерфейса.

Другая возможность - создать интерфейс-обертку, который возвращает значения по умолчанию для ненужных двух методов. Но в этом случае у вас также будет 3 интерфейса (и исходный родительский интерфейс - всего 4 интерфейса). Это решение будет приемлемым, если у вас нет возможности изменить исходный интерфейс.

0 голосов
/ 22 октября 2010

Я думаю, что вам может быть лучше объявить единственный чистый виртуальный метод для переопределения, но пусть он возвращает различенный союз или вариант / любой тип в этом первом аргументе.Затем каждый производный класс может возвращать желаемый тип.При вашем текущем способе вам нужно будет принять решение о том, какой метод вызывать.С дискриминационным объединением вы будете вызывать только один метод, но примите решение о том, что делать с ним после того, как он вернется.Очевидно, что я пропустил проверку ошибок и тому подобное, но она довольно похожа на то, что, я думаю, вы планируете делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...