在C++中为类提供可访问的"名称"时,您如何"不重复自己"?

The*_*zer 7 c++ dry

考虑以下:

class Base {
  public:
    virtual std::string getName() = 0;
    ...
};

class Derived1 : public Base {
  public:
    static std::string getClassName() { return("Derived1"); }
    std::string getName() { return("Derived1"); }
    ...
};

class Derived2 : public Base {
  public:
    static std::string getClassName() { return("Derived2"); }
    std::string getName() { return("Derived2"); }
    ...
};
Run Code Online (Sandbox Code Playgroud)

这个想法是,如果您将派生类作为模板参数传递,那么您可以通过它获取其类名getClassName,而如果您将它作为指向基类的指针传递,则可以通过获取名称getName.

我在这里看起来有很多类似的问题但是所有人似乎都在问"我如何使用静态虚拟","为什么不存在静态虚拟"以及类似的各种东西,而答案似乎是解决的问题不仅仅是我认为真正的潜在问题,那就是:我怎样才能避免重复使用该代码并在尽可能少的样板文件中提及名称两次?(不要重复自己,或干燥规则)

我也不想要一个宏.

Rei*_*ica 4

首先,您可以getClassName在以下位置重复使用getName:

class Derived1 : public Base {
  public:
    static std::string getClassName() { return("Derived1"); }
    std::string getName() override { return getClassName(); }
    ...
};
Run Code Online (Sandbox Code Playgroud)

现在, 的所有定义getName()都是相同的,因此您可以将它们放入宏中以节省键入时间(并使它们更加面向未来):

#define GET_NAME() std::string getName() override { return getClassName(); }

class Derived1 : public Base {
  public:
    static std::string getClassName() { return("Derived1"); }
    GET_NAME()
    ...
};
Run Code Online (Sandbox Code Playgroud)

getClassName或者你也可以在那里捆绑:

#define GET_NAME(maName) \
  static std::string getClassName() { return(maName); } \
  std::string getName() override { return getClassName(); }

class Derived1 : public Base {
  public:
    GET_NAME("Derived1")
    ...
};
Run Code Online (Sandbox Code Playgroud)

你说“我也不想要宏”,但宏是一个很好的工具,而且我不会发现像这样使用它们有任何问题。但是,如果这不是您想要的,您也可以不使用它们:

template <class Self>
struct GetName : public Base
{
  std::string getName() override { return Self::getClassName(); }
};

class Derived1 : public GetName<Derived1> {
  public:
    static std::string getClassName() { return("Derived1"); }
    ...
};

class Derived2 : public GetName<Derived2> {
  public:
    static std::string getClassName() { return("Derived2"); }
    ...
};
Run Code Online (Sandbox Code Playgroud)