【问题标题】:Which is better: explicit or typeless get()?哪个更好:显式或无类型 get()?
【发布时间】:2016-04-11 18:37:58
【问题描述】:

假设同一个A类有以下两个版本:

版本 1

class A
{
   public:
      enum class Retrievable { Integer, String };

      A(): m_integer(123), m_string("string") {}
      ~A() {}

      void* get(const Retrievable r)
      {
         switch (r)
         {
            case Retrievable::Integer:
               return static_cast<void*>(&m_integer);
            case Retrievable::String:
               return static_cast<void*>(&m_string);
            default:
               throw;
         }
      }

   private:
      int m_integer;
      std::string m_string;
};

第 2 版

class A
{
   public:
      A(): m_integer(123), m_string("string") {}
      ~A() {}

      int getInteger()        { return m_integer; }
      std::string getString() { return m_string;  }

   private:
      int m_integer;
      std::string m_string;
};

就清晰度、效率和可扩展性而言,这两种范式——单个无类型的 get() 函数或单独的显式 get() 函数——哪一个更好?

【问题讨论】:

  • 后者。在前者中,您需要同时指定参数r 和容易出错且多余的返回类型。也无法做到virtual。当您以某种方式使用指定类型时,前者很有用,例如dynamic_cast 但在这个例子中你没有。
  • 不编译的代码比编译的代码快。版本 1 无法编译,因此显然性能更好。等等,什么?如果您想知道选项 1 或选项 2 是否更好,请提供描述您的选项的实际工作代码。因为上述内容没有任何意义——我必须从根本上重写你的一个选项以使其编译,谁知道我是否会以同样的方式重写相同的代码。
  • @Yakk 老实说,我的编码还没有达到可以编译工作示例的程度。但是,由于其他原因,我最终使用了第二种方法。这是一个理论练习,我很想知道答案。我确信我可以得到这样的东西来编译。问题是关于它背后的理论,而不是我发布的具体内容(我认为它至少部分错误)。
  • @frost 除了你掩饰的部分——得到“这样的东西来编译”——对性能有影响。因为生成的代码看起来很少像您发布的那样,至少有 2 或 3 种不同的可能方式。当询问诸如性能之类的问题时,请询问您已编译的代码,而不是不起作用的代码
  • @Yakk 我已经将代码 sn-ps 更新为可以编译和工作的东西。

标签: performance c++11 extensibility


【解决方案1】:

选项 1 将事物转换为 void* 并进行运行时调度,这样会更慢、更不安全且更难使用。

除非与脚本引擎交互,否则我无法想象使用选项 1 的理由。即便如此,还有许多更好的方法来处理它。如果一位受访者提出选项 1 作为选项 2 的替代选择,那将是一个强烈的不雇用,这会让我重新考虑让受访者走到这一步的漏斗。

简而言之,方案 2 更好。

【讨论】:

    【解决方案2】:

    无论如何,版本 A 都不会编译,因为无论 C 是什么,您都会尝试返回不是 C 的类型(C 的指针是 string 等)

    B 版可能更好,但也别歪了。除非您正在构建诸如 JSON 节点之类的多态类型,否则该函数应该描述行为,而不是返回类型。

    再次,除非您正在编写一些 JSON 类,否则我认为创建一个描述返回类型而不是行为的函数没有多大意义。一个Person 没有getHandgetLeg 函数,他有wavewalk 等函数。

    表现?我怀疑吸气剂会破坏您的应用程序的性能。

    【讨论】:

    • 这些只是概念的通用名称。因此,例如,getInteger() 可能是 getCurrentGameLevel() 并返回 m_currentGameLevel。
    • 所以基本上比较是在get(Option::GameLevel)getGameLevel之间?毫无疑问第二个。因为它描述了行为并在编译时确定
    猜你喜欢
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2013-03-16
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多