c++ - 使用 lambda 调用私有(private)析构函数作为 std::shared_ptr 的删除器?

标签 c++ memory-management c++11 lambda anonymous-function

对于这个游戏,我有一个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/

相关文章:

c++ - 编译错误 : invalid use of void expression

C++ 以编程方式转换 : can it be done?

c++ - OpenCL 缓冲区分配和映射最佳实践

c++ - 记住最初的对象,它只能管理共享内存

python - append Python的内存效率.txt

java - 静态变量的实际内存位置是什么?

c++ - 在 C++ 中使用逗号运算符时的未定义行为

c++ - 基于范围的 for 循环等价物

c++ - 如果存在专门化,如何限制模板化函数?

c++ - Pythonic方式重写以下C++字符串处理代码