对于这个游戏,我有一个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();
}
正如你所看到的,我的lazy-initialize样式要求我使用智能指针,但是因为我试图避免使用公共析构函数,所以我必须使用lambda作为删除器,现在这段代码编译得很好,但是我似乎无法找到任何模式为什么一个lambda,由标准称为一个单独的独特对象,可以调用这个私有方法,特别是在查看SO上的一些问题之后:
我基本上想知道的是成员函数中lambda的访问规则,如示例...
答案 0 :(得分:3)
标准在5.1.2 / 3中说明
lambda-expression [...]的类型是一个独特的类类型 - 调用闭包类型[...]闭包类型在声明中声明 包含的最小块范围,类范围或命名空间范围 相应的lambda表达式。
这意味着在(成员)函数内发生的lambda被视为本地类,在周围函数的块作用域中声明。关于本地课程,标准在9.8 / 1中说:
[...]本地类属于封闭范围的范围,并且具有 对函数外部的名称的访问与封闭的名称相同 功能。[...]
因此lambda具有与包含成员函数相同的访问权限,这意味着它可以访问该类的私有成员。
如果lambda直接出现在类作用域中,它将被视为嵌套类,适用类似的规则:11.7 / 1表示:
嵌套类是成员,因此具有相同的访问权限 任何其他成员。
无论哪种方式,在类范围内发生的lambda都可以访问私有类成员。所以你的榜样很好。
(您提到的帖子,最终是关于访问由 qualified-id 命名的基类的受保护成员的问题。)