在C ++函数中使用本地类

时间:2011-04-19 09:56:24

标签: c++ design-patterns

我在c ++函数中看到了一些内部结构的用法。

有一个共同的接口IBase。这是草案代码。

class IBase
{
    virtual Method()=0;
}

vector<IBase*> baseList;

然后一个函数根据该IBase定义了一个内部类,然后将内部类对象推送到baseList中。

void func()
{
    struct Object : public IBase
    {
        virtual Method()
        {
            // Method of Object in func
        }
    }

    IBase* base = new Object();
    baseList->push(base);

}

这似乎是一种奇怪的用法,但是消息/事件创建模式的一个很好的实现。

其他线程可能使用此baseList来处理传入的事件。

“struct Object”的内部结构的范围是什么?这很有趣。是否有一些文件在讨论这个问题?

4 个答案:

答案 0 :(得分:42)

  

“struct Object”的内部结构的范围是什么?

本地类的范围是它们被定义的函数。但这本身并不感兴趣。

让本地类感兴趣的是如果它们实现了某些接口(就像你的代码一样),那么你可以创建它的实例(使用new)并返回它们(例如,作为std::vector<IBase*>),从而使实现通过基类指针可访问,甚至在函数外部。

关于本地课程的其他一些事实:

  • 他们无法定义静态成员变量。

  • 他们无法访问封闭函数的非静态“自动”局部变量。但他们可以访问static变量。

  • 它们可用于模板功能。

  • 如果它们是在模板函数中定义的,那么它们可以使用封闭函数的模板参数。

  • 本地类是final,这意味着函数外部的用户无法从本地类派生到函数。如果没有本地类,则必须在单独的翻译单元中添加未命名的命名空间。

  • 本地类用于创建trampoline functions,通常称为 thunks


修改

标准(2003)的一些参考文献

9.8本地类声明[class.local]

  

\ 1。可以在函数定义中定义类;这样的课是   叫一个本地班。一个名字   本地班级是其附近的本地班级   范围。本地类在范围内   封闭范围,并具有   同样访问外面的名字   与封闭一样起作用   功能。在当地的声明   class只能使用类型名称,静态   变量,外部变量和   来自的函数和枚举器   封闭范围。

[Example:

int x;
void f()
{
   static int s ;
   int x;
   extern int g();

   struct local {
      int g() { return x; } // error: x is auto
      int h() { return s; } // OK
      int k() { return ::x; } // OK
      int l() { return g(); } // OK
   };
// ...
}
local* p = 0; // error: local not in scope

—end example]
  

\ 2。封闭功能无法对本地成员进行特殊访问   类;它遵守通常的访问规则   (第11条)。一个成员的职能   本地班级应在其中定义   他们的班级定义,如果是的话   完全定义。

     

\ 3。如果类X是本地类,则可以声明嵌套类Y.   类X和后来定义的   X类的定义或稍后的定义   定义在相同的范围内   类X的定义。嵌套的类   在本地班级内是本地班级。

     

\ 4。本地类不应具有静态数据成员。

答案 1 :(得分:4)

\ 4。本地类不应具有静态数据成员。

但你可以在本地课堂内做到这一点

int GetCount()
{
    class _local
    {
    public:
        static int Count(int count = std::numeric_limits<int>::max())
        {
            static int count_ = 0;
            if (count != std::numeric_limits<int>::max()) count_ = count;
            return count_;
        }

        static float Operation(float  a, float  b)
        {
            _local::Count(_local::Count() + 1);
            return a;
        }
    };
   _local::Count(0);
   CALLBACK( _local::Operation);
   return _local::Count();
}

_local :: Count可用于读取和写入静态变量

-aydin

答案 2 :(得分:2)

这是正常的C ++。 struct Object范围只是函数func。但是,您仍然可以使用此类型的对象,而不知道它们是哪种具体类型,因为它们继承自IBase。这用于封装实现。

答案 3 :(得分:0)

Jason Turner在CppCon演讲中重点介绍了使用本地类的有趣用法,该演讲专注于用C ++ 17编写Commodore 64游戏。他展示了如何在功能级别上使用RAII原理。

他基本上在返回该类实例的函数中的局部类的构造函数中建立了不变式。因此,不变的持续时间由返回对象的生存期控制。它与std::lock之类的RAII包装非常相似,只是略有不同。

您可以see the appropriate part here,但我他的演奏,并建议从头到尾查看。