2016-04-08 2 views
2

У меня есть два класса. Первый класс делает что-то, а затем просто вызывает метод второго класса. Каждый метод первого класса делает это. Можно ли автоматизировать реализацию кода с помощью макроса?C++ предоставление имени функции макрокоманде и вызов его

Пример:

class A 
{ 
    void Do1() 
    { 
    Do task x 
    ClassB b; 
    b.Do1(); 
    Do task y 
    } 
    void Do2() 
    { 
    Do task x 
    ClassB b; 
    b.Do2(); 
    Do task y 
    } 
} 

Можно ли реализовать этот путь? Это не работает, но что-то похожее.

#define VOID_FUNC(name) \ 
    Do task x;\ 
    ClassB b;\ 
    b.##name##();\ 
    Do task y; 

class A 
{ 
    void Do1() 
    { 
    VOID_FUNC(__FUNCTION__); 
    } 
    void Do2() 
    { 
    VOID_FUNC(__FUNCTION__); 
    } 
} 
+0

Возможно, но симпатичный способ был бы использовать шаблоны, 'станд :: bind', и 'std :: function'. Я обязательно отвечу на этот вопрос. – Bathsheba

+0

Кажется, что нет простого способа создать то, что вы просите, и не очень-то простые способы получить уродливые реальные быстро; это может помочь, если вы объясните, почему вы хотите это сделать, поскольку может быть лучший способ выполнить вашу задачу? Похоже, вы хотите написать обертку вокруг существующего класса, который управляет каким-то ресурсом, который использует класс, где задача x будет приобретать ресурс, а задача y выведет его. Одна из идей, которая пришла мне в голову, заключается в том, что стандартная библиотека C++ обычно позволяет настраивать пользовательские распределители, которые могут быть адаптированы даже для таких вещей, как ведение журнала. –

ответ

2

Есть много веских причин избежать макросов, поскольку они не уважают пространства имен.

Другим решением является использование лямбда-функций (C++ 11 и позже), когда вы хотите использовать task x и task y:

class A 
{ 
    template <typename Fun> 
    void wrapClassB(Fun&& fun) 
    { 
    Do task x 
    ClassB b; 
    fun(b); 
    Do task y 
    } 

    void Do1() 
    { 
    wrapClassB([] (ClassB& b) { 
    b.Do1(); 
    }); 
    } 
    void Do2() 
    { 
    wrapClassB([] (ClassB& b) { 
    b.Do2(); 
    }); 
    } 
}; 

Для предварительного C++ 11 вы можете создать functors вместо лямбды и замените Fun&& на const Fun&.

В качестве альтернативы, если вы действительно хотите использовать макросы, вы можете просто определить всю функцию с помощью макроса:

#define VOID_FUNC(name) \ 
    void name() {\ 
    Do task x;\ 
    ClassB b;\ 
    b.name();\ 
    Do task y;\ 
    } 
class A 
{ 
    VOID_FUNC(Do1) 
    VOID_FUNC(Do2) 
}; 
+2

C++ 11 добавил лямбда, но это всего лишь очень удобный способ построения функторов. Вы можете отправить их обратно в 1998 году. – MSalters

+0

Уверен, что вы можете @MSalters, хорошо! Я немного обновил ответ – Hilborn

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