How to replace this macro with inheritance or pattern (or something else?)

My question is similar to: You cannot use the macro combination class in C ++ , but a little more complicated:

class ABC
{
public:
    DECLARATION(ABC)

private:
    void ABCFun1();
    void ABCFun2();
    // ... and so on
}

#define DECLARATION(TYPE)\
    std::string GetClassName()\
    {\
        return std::string(#TYPE);
    }\
    // the macro can goes on to declare more
    // common interfaces, like Initialize(), ...etc.

So the thing is, I can use this macro to create other classes, such as DEF, GHI..., etc.,
where they all share a common part DECLARATION, but also have their own private
parts.

If there is no need GetClassName(), which, it seems, can only be realized with a macro #,
then I can use inheritance to put them together.
Or, if there are no personal items, I can use a template.

So, with these two things confused, is there a way to avoid the macro?
Thanks!

+4
3

CTRP . , , ( , , , ++ 17).

CRTP

template<typename T>
class Base
{
public:
    void myFunc()
    {
        ((T*)this)->functionA();
        ((T*)this)->functionB();
        // ...
    }
};

class ABC : public Base<ABC>
{
    // ...
};

: BЈћ , RTTI:

  • .
  • typeid(T).name() ( "" , )
  • .

RTTI LLVM, ( ).

, . , (.. template<typename T>, #T "T", ). , (sort-of):

#define NAME( _n_ , _t_ )             \
    struct _t_                        \
    {                                 \
        static const char* asName()   \
        {                             \
            return #_n_;              \
        }                             \
    }

. , ( , , , ).

SPARK Particle Engine, , .

+2

" ..." DECLARATION, , :

  • define ABC
  • ( ), ABC
  • , "ABC"

tl; dr: # 1 , . # 2 , CRTP, # 3 .

:

, , "". ++. (. " " )

- , .

, CRTP: , , :

template <class T>
class Base {
public:
  void doSomething(T const&);
};

class ABC : public Base<ABC> {
  // inherited void doSomething(ABC const&);
};

, , .

++ , , ( , , ...) , . ( , ). typeid(T).name(), , , - , .

, ( ) "ABC" ABC, "ABC" . , - # 2, ABC ABC .

:. , , , . , , /:

class ABC {
  DECLARATION(ACB);
};

, , - ( , ACB ). , , , :

#define CLASS_DEF(x)           \
class x##_base {               \
  std::string GetClassName() { \
    return std::string(#x);    \
  }                            \
};                             \
class x : public x##_base

:

CLASS_DEF(ABC)
{
private:
    void ABCFun1();
    void ABCFun2();
    // ... and so on
}

, .

, # 3 , ?

  • , , , . . , , boost::mpl::string<'Hell','o Wo','rld!'>, . , ++ 11 , ( boost::mpl::string), , , . -, # 2 # 3, ( , )

    class ABCDE: public Base<ABCDE, 'ABCD', 'E'> { /* ... */ }
    
  • , . , CRTP, :

    template <class T>
    class Base {
    public:
      std::string GetClassName() const {
        return T::name;
      };
    };
    
    class ABC : public Base<ABC> {
    public:
      constexpr static char const *  name = "ABC";
    };
    

    ++ 03 static const, (.. ABC.cpp)

  • , ABC, :

    template <class T>
    class Base {
    public:
      std::string GetClassName() const {
        return static_cast<T const*>(this)->name;
      };
    };
    
    class ABC : public Base<ABC> {
    public:
      const std::string name = "ABC";
    };
    

    ++ 11. ++ 03 .

  • , , imo, , , , CRTP do # 2:

    class Base {
    public:
      Base(std::string nm) : name(nm) {}
      std::string GetClassName() const {
        return name;
      };
      std::string name;
    };
    
    class ABC : public Base {
    public:
      ABC() : Base("ABC") {}
      ABC(int i) : ABC() { /*another ctor*/ }
    };
    

    Base , ++ 11, Base("ABC") ABC() .

+1

, typeinfo:: name().

CRTP, , . - :

template< typename T >
class MyBase
{
  public:
    MyBase() : className( typeid(T).name() ){}
    virtual ~MyBase(){}


    std::string className;
    // common interfaces, like Initialize()
};

:

class A : public MyBase<A>
{
};
0

Source: https://habr.com/ru/post/1529169/


All Articles