2017-01-01 3 views
1

Я разрабатываю проект, где я хочу, чтобы было возможно указать, какой из нескольких классов методов/алгоритмов/функций должен использоваться. Каждый метод «класс» предоставляет аналогичные функции и является взаимозаменяемым с другими классами.Можно ли использовать производный класс, например, использовать статическую функцию класса?

Я пытался реализовать это с базовым абстрактным классом с методом «классы» в качестве производных классов:

class Method { 
public: 
    virtual int function1(int) = 0; 
    virtual int function2(int, int) = 0; 
}; 

class Method1 : public Method { 
public: 
    int function1(int a) { 
     return a * 2; 
    } 

    int function2(int a, int b) { 
     return a + b; 
    } 
}; 

class Method2 : public Method { 
public: 
    int function1(int a) { 
     return a/2; 
    } 

    int function2(int a, int b) { 
     return a - b; 
    } 
}; 

void useMethod(int a, int b, Method& m) { 
    int result1 = m.function1(a); 
    int result2 = m.function2(a, b); 

    /* Do something with the results here */ 
} 

int main() { 
    // Doesn't work, "type name is not allowed" 
    useMethod(1, 2, Method1); 
    useMethod(1, 2, Method2); 

    // Works, but seems unnecessary and less elegant 
    Method1 x; 
    useMethod(1, 2, x); 
    Method2 y; 
    useMethod(1, 2, y); 

    return 0; 
} 

Проблема заключается в том, что я не могу показаться, чтобы выяснить, как разрешить использование Method1 и Method2 без создания их экземпляров, которые мне кажутся ненужными, так как все они будут предоставлять одни и те же функции. Есть ли способ сделать производные классы «статичными», чтобы их можно было использовать без экземпляров?

+1

Возможный дубликат http://stackoverflow.com/questions/1820477/c-static-virtual-members – UnholySheep

+0

Также я не считаю, что наследование - это совершенно правильный подход. Я думаю, что использование шаблонов и/или указателей функций (или 'std :: function') будет иметь больше смысла. – UnholySheep

+0

@UnholySheep. Не могли бы вы рассказать о том, как« std :: function »может предоставить лучшее решение? Разве это не просто оболочка функции? –

ответ

4

Вы могли бы сделать просто:

useMethod(1, 2, Method1()); 
useMethod(1, 2, Method2()); 

В противном случае нет, вы не можешь иметь static virtual метод. Вы можете достичь подобную вещь с шаблонами хотя:

template<typename T> 
void useMethod(int a, int b) 
{ 
    int result1 = T().function1(a); //or if you made the methods static then T::method1(a) 
    int result2 = T().function2(a, b); //ditto 

    /* Do something with the results here */ 
} 

И использование:

useMethod<Method1>(1, 2); 

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

+0

Стоит отметить, что это по сути то же самое, что и вторая попытка OPs, за исключением того, что вы создаете объекты непосредственно в вызове функции, а не сначала присваиваете их переменным. – UnholySheep

+0

@ UnholySheep Да, это было сделано как доказательство того, что оно не «менее изящно». Добавлена ​​версия шаблона, чтобы показать альтернативный подход без полиморфизма. – Resurrection

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