0

对于这个游戏,我有一个 Game 类,它是一个单例......这是头文件

#ifndef SOKOBAN_GAME_H
#define SOKOBAN_GAME_H
#include <memory>
#include <SDL/SDL.h>
namespace sokoban
{
  class Game
  {
  public:
    static Game* getInstance();
    void startGame();
  private:
    Game();
    ~Game();
    Game(const Game&) = delete;
    Game(Game&&) = delete;
    Game& operator=(const Game&) = delete;
    Game& operator=(Game&&) = delete;

    static std::shared_ptr<Game> instance_;
    SDL_Surface* mainSurface_;
  };
};
#endif

现在,除了 getInstance 函数之外,大部分实现文件都不重要了:

Game* Game::getInstance()
{
  if(!Game::instance_)
  {
    Game::instance_ = std::shared_ptr<Game>(new Game,
    [](Game* ptr)
    {
      delete ptr;
    });
  }

  return Game::instance_.get();
}

如您所见,我的惰性初始化样式要求我使用智能指针,但是因为我试图避免使用公共析构函数,所以我必须使用 lambda 作为删除器,现在这段代码编译得很好,但是我不能似乎找到了为什么标准所说的 lambda 是一个单独的唯一对象的任何模式,可以调用这个私有方法,特别是在查看了一些关于 SO 的问题之后,例如:

我基本上想知道的是成员函数中 lambda 的访问规则,例如示例...

4

1 回答 1

3

该标准在 5.1.2/3 中说

lambda 表达式 [...] 的类型是唯一的 [...] 类类型 — 称为闭包类型 [...] 闭包类型在最小的块范围、类范围或命名空间范围中声明包含相应的 lambda 表达式。

这意味着发生在(成员)函数内部的 lambda 被视为本地类,在周围函数的块范围内声明。关于本地课程,标准在 9.8/1 中说:

[...]本地类在封闭范围的范围内,并且与封闭函数一样具有对函数外部名称的相同访问权限。 [...]

因此 lambda 具有与包含成员函数相同的访问权限,这意味着它可以访问类的私有成员。

如果 lambda 直接出现在类范围内,它将被视为嵌套类,适用类似规则:11.7/1 说:

嵌套类是成员,因此具有与任何其他成员相同的访问权限。

无论哪种方式,出现在类范围内的 lambda 都可以访问私有类成员。所以你的例子很好。

(您提到的帖子最终是关于访问由qualified-id命名的基类的受保护成员的问题。)

于 2013-02-10T23:54:29.387 回答