【问题标题】:C++ unique_ptr versus friend class private destructorC++ unique_ptr 与友元类私有析构函数
【发布时间】:2013-02-18 01:00:59
【问题描述】:

我有这样的安排:

class LexedFile
    {
    friend class Lex;
//...
private:
    ~LexedFile();
    };

class Lex
    {
//...
private:
    std::map<std::string, std::unique_ptr<LexedFile> > Files;
    };

Lex 是LexedFile 对象的唯一创建者,并保留它在地图中创建的所有LexedFile 对象的所有权。不幸的是,由于从映射变量到LexedFile 析构函数的可见性规则,编译器对此非常抱怨。我可以通过将~LexedFile() 设为公开来解决该问题,但我将其设为私有的原因当然是为了强化该类型的对象仅属于Lex 对象的决定。

我的问题是:我有哪些便携选项可以让unique_ptr 开心并保持~LexedFile() 私密?通过便携,我想它至少必须与最新的 g++ 和最新的 Visual C++ 一起工作。

我尝试插入类似的东西:

friend class std::unique_ptr<LexedFile>;

但即使它起作用了(它没有起作用),它似乎有点依赖于对可能不可移植的实现的假设。

【问题讨论】:

  • 传递你自己的删除器而不是使用默认的:)
  • friend class std::default_delete&lt;LexedFile&gt; 也可能工作,具体取决于实现,但我不会指望它,它也可能暴露你的析构函数而不是你希望它被暴露
  • 或者更好的friend std::unique_ptr&lt;LexedFile&gt;::deleter_type;,它也适用于使用自定义删除器的std::unique_ptr。

标签: c++ map destructor friend unique-ptr


【解决方案1】:

只需使用您自己的删除器实例化std::unique_ptr。我认为这会奏效:

class LexedFile
{
    friend class Lex;

//...
private:
    struct Deleter
    {
        void operator()(LexedFile *file) const
        {
            delete file;
        }
    };

    ~LexedFile();
};

class Lex
{
//...
private:
    std::map<std::string, std::unique_ptr<LexedFile, LexedFile::Deleter>> Files;
};

【讨论】:

  • 感谢您的帮助!在等待(几乎)标准的下载并四处寻找之后,我决定使用您的朋友声明。看起来它应该是可移植的(在将“类”更改为“结构”之后),而制作包装器只是为了对抗权限的替代方案令人沮丧。 :-) 无论它可能有什么漏洞,它绝对仍然禁止任何直接在该类上调用 delete 的人,这是我想要工作的主要提醒。再次感谢!
  • @RonBurk 顺便说一句,我几乎可以肯定你依赖于未定义的行为,只要你对此表示满意。
  • 怎么样? 20.7.1 似乎需要 unique_ptr 才能使用 default_delete。我错过了什么?
  • 我认为不能保证 default_delete 直接调用 delete
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 2021-10-13
  • 2013-03-27
  • 2013-10-16
  • 2023-03-31
  • 2019-01-08
相关资源
最近更新 更多