您如何“不重复自己”?当给一个班级一个可访问的“名称”时在C ++中? [英] How do you "not repeat yourself" when giving a class an accessible "name" in C++?

查看:61
本文介绍了您如何“不重复自己”?当给一个班级一个可访问的“名称”时在C ++中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下内容:

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

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

The idea is that if you have the derived class passed as, say, a template parameter, then you can get its class name via getClassName, while if you have it passed as a pointer to base class, you can get the name via getName.

我在这里似乎有很多类似的问题,但所有人似乎都在问诸如如何使用静态虚拟机之类的问题, 为什么不存在静态虚拟机和类似的东西,答案似乎超出了我认为真正的根本问题,即:如何避免重复使用该代码自己并在使用尽可能少的样板时再提两次名称? (不要重复您自己或DRY规则)

I have seem a lot of similar questions to this here but all of them seem to ask stuff like "how do I use a static virtual", "why don't static virtuals exist" and various stuff like that, and the answers seem to address that more than what I think the real underlying problem is, which is: how can I avoid having to repeat myself with that code and mentioning the name twice while using as little boilerplate as possible? (Don't Repeat Yourself, or DRY Rule)

我也不需要宏。

推荐答案

首先,您可以在 getName getClassName c>:

First off, you can re-use getClassName in getName:

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

现在,所有 getName()的定义完全相同,因此您可以将它们放在宏中以节省键入(并使它们更适合未来使用):

Now, all definitions of getName() are identical, so you can put them in a macro to save on typing (and make them more future-proof):

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

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

或者您也可以在其中捆绑 getClassName 好:

Or you can bundle getClassName in there as well:

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

class Derived1 : public Base {
  public:
    GET_NAME("Derived1")
    ...
};

您说我也不想要一个宏,但是宏是一个很好的工具这样,这样使用它们不会出现任何问题。但是,如果这不是您想要的,您也可以在没有它们的情况下执行此操作:

You say "I don't want a macro, either," but macros are a good tool for that, and I wouldn't see a single problem with using them like this. However, if that is not what you want, you can do it without them as well:

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

这篇关于您如何“不重复自己”?当给一个班级一个可访问的“名称”时在C ++中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆