【问题标题】:Iterating through vector of unique_ptr of a struct with private destructor, by a friend, fails in VS 2017一位朋友在 VS 2017 中迭代具有私有析构函数的结构的 unique_ptr 向量失败
【发布时间】:2019-01-08 02:59:51
【问题描述】:

这可能是一个简单答案的问题,但我尝试了谷歌结果提供的所有解决方案,但无法在 VS 2017 中解决此问题。我有一个带有私有析构函数的结构 B。我有另一个结构A 是结构B 的朋友,并尝试遍历指向结构B 的唯一指针向量。但我不断收到此错误:

严重性代码描述项目文件行抑制状态 错误 C2248“ProjectNamespace::NwSpec::~NwSpec”:无法访问在类“ProjectNamespace::NwSpec”TestProject c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\ 中声明的私有成员14.14.26428\包括\内存2055

任何指针将不胜感激。谢谢。

        struct A
        {
        //functions
        std::vector<std::unique_ptr<NwSpec>> List;
        bool function()const;
        };

        struct NwSpec
        {
            char* Path;//Assume Path is initialized and set with a string.

            private:
                ~NwSpec();

            friend struct A;
        };

        bool A::function()const 
        {
            for (uint32_t i = 0 ; i < List.size(); i++)
            {

            OutputDebugStringA(List[i]->Path);// Error C2248
            }
            // I used iterator to the vector, but getting same error.
            // I used for(const auto& k : List) but getting same access error.
            // NwSpec is visible to A and within ProjectNamespace
        }

【问题讨论】:

  • 什么是Path
  • 路径是 char* 路径
  • 什么是Struct
  • 停下来。想想你想发布什么并发布代码。两分钟内修改六次是在浪费大家的时间。
  • NwSpec 的析构函数声明为私有的预期目的是什么? std::unique_ptr 如果无法访问它,将无法删除它,这是您错误的根本原因。如果这个决定是任意的,我会发布这个作为答案,但我怀疑这是一个XY-Problem,首先将析构函数设为私有的决定更接近根本问题。

标签: c++ visual-studio-2017 stdvector unique-ptr friend


【解决方案1】:

您需要创建一个专门的类型来负责删除 NwSpec 对象,并将其提供给std::unique_ptr

struct NwSpec;

struct A {
private:
    struct NwSpecDeleter {
        //Note that we're only declaring the function, and not defining it
        void operator()(NwSpec * ptr) const;
    };
public:
    typedef std::unique_ptr<NwSpec, NwSpecDeleter> ptr_type;
    std::vector<ptr_type> List;
    bool function()const;
};

struct NwSpec {
    char* Path;//Assume Path is initialized and set with a string.

private:
    ~NwSpec();

    friend struct A;
};

NwSpec::~NwSpec() {}

void A::NwSpecDeleter::operator()(NwSpec * ptr) const {
    delete ptr;
}

int main() {
    A a;
    a.List.emplace_back(new NwSpec());
    auto ptr = a.List.back().release();
    //This will not compile, as intended
    //delete ptr;
    //Nor will this:
    //ptr->~NwSpec();
    //But this will compile, because the original unique_ptr is perfectly capable of deleting objects:
    a.List.back().reset(ptr);
    a.List.back().reset();//Object is successfully deleted

    a.List.erase(a.List.begin(), a.List.end());
    a.List.emplace_back(new NwSpec());
    //This also compiles
    a.List.erase(a.List.begin(), a.List.end());
    return 0;
}

此代码可以是tested here

【讨论】:

  • 工作。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2013-02-18
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
  • 2013-10-16
相关资源
最近更新 更多