В моем базовом классе B.cpp у меня есть макрос
#define PRODUCT "MY PRODUCT B"
который используется в многочисленных выходных данных и т. д. Теперь я получил класс D из B и хотел бы заменить макрос на
#define PRODUCT "NEW PRODUCT D"
Есть ли способ сделать это? Это просто сводится к порядку компиляции (случайным образом)?
Вариант ответа Эдгара, который может быть более подходящим или менее подходящим в зависимости от того, чего вы пытаетесь достичь:
class Base {
private:
virtual const std::string Product() const {
return "MY PRODUCT B";
}
};
class Derived {
private:
virtual const std::string Product() const override {
return "MY PRODUCT D";
}
};
Если вы ответите лучше Эдгара, я бы предпочел, чтобы вы ответили Эдгару за ответ на вопрос.
Я не думаю, что макросы являются надежным способом достижения этого.
Вместо этого я предлагаю использовать статические элементы:
class Base {
private:
static const std::string PRODUCT;
};
const std::string Base::PRODUCT = "MY PRODUCT B";
class Derived {
private:
static const std::string PRODUCT;
};
const std::string Derived::PRODUCT = "MY PRODUCT D";
Теперь вы можете использовать PRODUCT
в обоих Base
а также Derived
классы.
Почему следует избегать макросов в C ++
Макросы пересекают границы, как громко сообщается в описании вашего примера.
Это просто сводится к порядку компиляции (случайным образом)?
У меня никогда не бывает случайного порядка компиляции, но я использую make-файлы, где зависимости управляют порядком. Обратите внимание, ваши сборки также должны быть повторяемыми.
Есть ли способ сделать это? [переопределить макрос для изменения только там, где это необходимо]
Возможно … вы можете надежно «#undef PRODUCT» непосредственно перед определением второго «#define PRODUCT …» И не иметь второго определения, видимого кодом, в котором вы хотите первое определение.
Рассматривать:
создать две зоны в вашем коде …
#define PRODUCT "MY PRODUCT B"
// zone a
#undef PRODUCT#define PRODUCT "NEW PRODUCT D"
// zone b
#undef PRODUCT
Поместите код, соответствующий и зависящий от определения, в соответствующую зону.
Одно из решений:
У меня были сюрпризы макросов со сторонним кодом, содержащим макросы, которые перепутались с именами моих символов. Это как если бы они определили макросы с обычно используемым значением, таким как: open, close, read, write и т. Д. Мой метод «Foo_t :: open ()» и т. Д. Был бы остановлен.
Я решил эту проблему (возможно, неуклюже)
а также