【问题标题】:When do I need anonymous class in C++?我什么时候需要 C++ 中的匿名类?
【发布时间】:2012-04-09 10:58:25
【问题描述】:

C++ 中有一个叫做匿名类的特性。它与 C 中的匿名结构类似。我认为这个功能是出于某些需要而发明的,但我不知道那是什么。

我可以举一些真正需要匿名类的例子吗?

【问题讨论】:

  • 为什么会有匿名结构?
  • @Nawaz 啊,是的,你是对的。我可能与它存在于 C 上的原因相同。无论如何,我对专门针对 C++ 的案例感到好奇。因为 C++ 与 C 语言有很大不同。

标签: c++ anonymous-class


【解决方案1】:

之所以有这个功能,是因为structclass 是同一个东西——你可以用一个做任何事情,你可以用另一个做任何事情。它的用途与 C 中的匿名 struct 完全相同;当您想将一些东西组合在一起并声明它的一个或多个实例,但不需要按名称引用该类型时。

它在 C++ 中不太常用,部分原因是 C++ 设计倾向于更面向类型,部分原因是您不能为匿名类声明构造函数或析构函数。

【讨论】:

    【解决方案2】:

    从严格意义上说,它并不是真正需要的,而且从来都不是。 IE。您总是可以指定一个名称,例如anonymous1anonymous2 等。但是跟踪不必要的名称总是很麻烦。

    有用的地方是在任何想要对数据进行分组而不给该组命名的地方。我可以举几个例子:

    class foo {
      class {
      public:
        void validate( int x ) { m_x = x; }
        bool valid() { return m_exists; }
      private:
        int m_x;
        bool m_exists;
      } maybe_x;
    };
    

    在这种情况下,intbool 在逻辑上属于一起,因此将它们分组是有意义的。然而,对于这个具体的例子,创建一个实际的可选类型或使用其中一个可用的类型可能是有意义的,因为这种模式也很可能在其他地方使用。在其他情况下,这种分组模式可能非常特别,以至于它应该只留在那个类中。

    我确实假设匿名类很少使用(我可能只在生活中使用过几次)。通常,当人们想要对数据进行分组时,这不是特定于类或范围的,而是一种在其他地方也有意义的分组。

    【讨论】:

    • 您的示例将需要一个构造函数来确保类不变(值有效或标志为假);但不能为匿名类声明构造函数。
    • @MikeSeymour:好点。我想一个人将不得不以其他方式来解决这个问题。也许在类初始化程序中使用 C++11 就可以了。正如我所说,这很可能是一个很少使用的功能。
    【解决方案3】:

    也许创建嵌套函数有时会有所帮助:

    void foo() {
      class {
        void operator()(){
        }
      } bar;
      bar();
    }
    

    但现在我们有了 lambda,并且仅出于兼容性原因才留下匿名类。

    【讨论】:

      【解决方案4】:

      匿名类的使用是为了保持与现有 C 代码的兼容性。 示例:

      在某些 C 代码中,将 typedef 与匿名结构结合使用很普遍。

      【讨论】:

        【解决方案5】:

        有一个匿名结构的示例,可以与 Qt 5 的 Signal/Slot 系统一起使用,具有 ANY 类且无需 QObject 派生要求:

        void WorkspaceWidget::wwShowEvent()
        {
            //Show event: query a reload of the saved state and geometry
            gcmessage("wwShowEvent "+ this->title());
            struct{void* t; void operator()(){ static_cast<WorkspaceWidget*>(t)->wwReloadWindowState(); }}f;
            f.t=this;
            QObject::connect( &reloadStateTimer, &QTimer::timeout, f);
            reloadStateTimer.start();
        }
        
        void WorkspaceWidget::wwReloadWindowState()
        {
            gcmessage( dynamic_cast<QObject*>(this)->metaObject()->className());
        }
        

        基本上,我需要将计时器信号连接到非 QObject 派生类,但想正确传递 mt "this"。

        QObject::connect 可以连接到Qt 5中的普通函数,所以这个匿名类实际上是一个函子,它本身保持this指针,仍然传递槽连接。

        【讨论】:

        • 但在 C++11 中用 lambda 替换会更好
        • 在撰写本文时,QObject 无法理解“Lambda”是什么,但后来他们修复了它。
        【解决方案6】:

        您还可以在匿名中使用 auto 进行操作(vs2015)

        struct {
        
            auto* operator->() {return this;}
            //do other functions
        
        } mystruct;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-01-19
          • 1970-01-01
          • 2012-12-05
          • 1970-01-01
          • 2010-09-21
          • 2018-02-25
          • 1970-01-01
          相关资源
          最近更新 更多