2012-07-02 2 views
1

Есть ли механизм на C++, который я мог бы использовать для реализации макроса, так что макрос определяет класс и в то же время множественные вызовы макроса не приводят к ошибке переопределения класса ? Благодаря!Избегание переопределения макроопределенного класса

ответ

0

Поскольку макрос не может сгенерировать какие-либо директивы препроцессора C++, не существует способа для определения макроса для генерации #define, который защищает от повторного создания. Вы должны были бы справиться с отдельными органами управления препроцессором, как-то:

#define CLASS_GENERATOR_MACRO(x, y, z) ...defines class x with attributes y, z... 

#ifndef GENERATED_CLASS_A 
#define GENERATED_CLASS_A 
CLASS_GENERATOR_MACRO(a, int, vector<std::string>); 
#endif /* GENERATED_CLASS_A */ 

Однако, нет ничего, что автоматически обеспечивает соблюдение только одно использование CLASS_GENERATOR_MACRO для создания класса a. То есть, файл может также содержать:

CLASS_GENERATOR_MACRO(a, double, double); 

и компилятор будет жаловаться на переопределение класса (если оба появляются в том же объеме).

Макрос может генерировать вызов _Pragma. Есть внешний шанс, что ваша система обеспечивает прагму, которая может помочь. Но, скорее всего, это не портативное решение, использующее прагмы.

-1

Это решение предполагает, что желаемое поведение заключается в создании экземпляра нового класса при каждом использовании макроса, но с разными именами.

Можно комбинировать использование __LINE__ macro и pre-processor token pasting operator ##, чтобы генерировать уникальные маркеры во время создания макросов.

#define LOCAL_CLASS(_Base) class _Base ## __LINE__ { /* class definition */ } 

Это может быть использован как таковой:

LOCAL_CLASS(SomeBase); 
LOCAL_CLASS(SomeBase); 

, который будет генерировать следующий код (при условии, что макросы инстанцируются в строках 2 и 3 исходного файла:

class SomeBase2 { /* class definition */ }; 
class SomeBase3 { /* class definition */ }; 

Недостатком этого решения является то, что имя сгенерированного класса изменяется в зависимости от того, где в объявленном файле, и поэтому нельзя полагаться. Это не проблема, если, скажем, класс n ot предназначен для потребления пользователем макроса; класс содержит информацию, которая автоматически регистрируется макросом с помощью внешней библиотеки.

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