-1

In my base class B.cpp I have a macro

#define PRODUCT "MY PRODUCT B"

which is used in numerous outputs etc. I now derive class D from B, and would to replace the macro with

#define PRODUCT "NEW PRODUCT D"

Is there a way to do this? Does it just come down to compilation order (random)?

TSG
  • 4,242
  • 9
  • 61
  • 121

3 Answers3

2

A variation on Edgar's answer, which may be more suitable or less suitable depending on what you are trying to accomplish:

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";
  }
};

If you this answer better than Edgar's, I'd rather you give Edgar credit for answering the question.

Eljay
  • 4,648
  • 3
  • 16
  • 27
  • Interesting idea. Why should the method in the Derived also be virtual? – TSG Jan 15 '18 at 21:28
  • @TSG It is virtual because the language spec says so. But it isn't necessary to write `virtual` in the derived class. It is redundant. – juanchopanza Jan 15 '18 at 21:29
1

I do not think macros are reliable way to achieve this.

I suggest using static members instead:

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";

Now you are able to use PRODUCT in both Base and Derived classes.

Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
0

Why should macro's be avoided in C++

Macros cross scope boundaries, as your example description loudly reports.

Does it just come down to compilation order (random)?

I never have random compilation order, but I use makefiles where the dependencies control the order. Note, your builds should also be repeatable.

Is there a way to do this? [redefine the macro to change only where desired]

Possibly ... can you reliably "#undef PRODUCT" just before the defining the second "#define PRODUCT ..." AND not have the second definition seen by code in which you want the first definition.

Consider:

create two zones in your code ...

#define PRODUCT "MY PRODUCT B"

// zone a

#undef  PRODUCT


#define PRODUCT "NEW PRODUCT D"

// zone b

#undef  PRODUCT

Put code corresponding to and dependent on the definition in to the appropriate zone.


One solution:

I had macro surprises with a 3rd party code containing macros which messed with my symbol names. Its as if they had defined macros with commonly used meaning like: open, close, read, write, etc. My method "Foo_t::open()" etc. would be stomped on.

I solved this issue (perhaps clumsily) by

  • including the 3rd party header in one cpp ONLY, such that the 'macros' I did use were only invoked by the code I wrote to use it, not in any other compilation unit. (i.e. I controlled where I introduced the macros via #include.)

and

  • adding a few somewhat 'higher-level' c++ methods below that include, this is the code which made use of the macros. These 'higher-level' c++ methods were declared in hpp, and defined in the cpp. Other code used these methods ... I suppose in some sense I 'wrapped' the macros.
2785528
  • 5,438
  • 2
  • 18
  • 20