对于这个游戏,我有一个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();
}
如您所见,我的惰性初始化风格要求我使用智能指针,但是因为我试图避免公共(public)析构函数,所以我必须使用 lambda 作为删除器,现在这段代码编译正常,但是我似乎找不到任何模式来说明为什么 lambda(按照标准说是一个单独的唯一对象)可以调用这个私有(private)方法,尤其是在查看了一些关于 SO 的问题之后:
我基本上想知道的是像示例这样的成员函数中 lambda 的访问规则...
最佳答案
标准在5.1.2/3中说
The type of the lambda-expression [...] is a unique [...] class type — called the closure type [...] The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.
这意味着出现在(成员)函数内部的 lambda 被视为本地类,在周围函数的 block 范围内声明。关于本地类,标准在 9.8/1 中说:
[...] The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function.[...]
因此 lambda 具有与包含成员函数相同的访问权限,这意味着它可以访问类的私有(private)成员。
如果 lambda 直接出现在类作用域中,它将被视为嵌套类,适用类似的规则:11.7/1 说:
A nested class is a member and as such has the same access rights as any other member.
无论哪种方式,出现在类范围内的 lambda 都可以访问私有(private)类成员。所以你的例子很好。
(您提到的帖子最终是关于访问由 qualified-id 命名的基类的 protected 成员的问题。)
关于c++ - 使用 lambda 调用私有(private)析构函数作为 std::shared_ptr 的删除器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14801591/