Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++容器,当被破坏时自动删除元素 < >我想创建C++中的引用列表或映射,在其销毁时自动删除其元素。下面是一个结构来演示这个想法 class Foo; class Bar { Foo foo; }; void main(void) { std::vector<Foo> foos; { Bar bar; foos.push_back(bar.foo); // foos[0] should be the same reference as bar.foo } // bar is now destructed // foos.size() should be 0 }_C++_List_Reference_Destructor - Fatal编程技术网

C++容器,当被破坏时自动删除元素 < >我想创建C++中的引用列表或映射,在其销毁时自动删除其元素。下面是一个结构来演示这个想法 class Foo; class Bar { Foo foo; }; void main(void) { std::vector<Foo> foos; { Bar bar; foos.push_back(bar.foo); // foos[0] should be the same reference as bar.foo } // bar is now destructed // foos.size() should be 0 }

C++容器,当被破坏时自动删除元素 < >我想创建C++中的引用列表或映射,在其销毁时自动删除其元素。下面是一个结构来演示这个想法 class Foo; class Bar { Foo foo; }; void main(void) { std::vector<Foo> foos; { Bar bar; foos.push_back(bar.foo); // foos[0] should be the same reference as bar.foo } // bar is now destructed // foos.size() should be 0 },c++,list,reference,destructor,C++,List,Reference,Destructor,我的代码有两个问题。当使用std::vector调用push_back时,它会创建Foo对象的副本。这是不可接受的,因为foos的元素应该反映对bar.foo所做的任何更改。其次,即使foos向量可以存储引用,在离开创建bar的范围后,Foo对象也不会从列表中删除。理想情况下,我希望Foo引用在销毁后从foos中删除 在我实现我自己的解决方案之前,我想知道有没有第三方库,可能吗?它提供了这个,或者我应该使用的任何适当的技术或策略。谢谢 我认为最好的选择是使用弱指针容器。如果您的编译器由于某种原因

我的代码有两个问题。当使用std::vector调用push_back时,它会创建Foo对象的副本。这是不可接受的,因为foos的元素应该反映对bar.foo所做的任何更改。其次,即使foos向量可以存储引用,在离开创建bar的范围后,Foo对象也不会从列表中删除。理想情况下,我希望Foo引用在销毁后从foos中删除


在我实现我自己的解决方案之前,我想知道有没有第三方库,可能吗?它提供了这个,或者我应该使用的任何适当的技术或策略。谢谢

我认为最好的选择是使用弱指针容器。如果您的编译器由于某种原因不支持C++11或TR1,则在Boost中可用

当目标被破坏时,弱指针将自动失效,假设您正确初始化了对象

下面是一些示例代码,用于获取弱指针容器中的所有有效指针

template <class T>
std::vector<std::shared_ptr<T> > MassLock(const std::vector<std::weak_ptr<T> >& weakptrs)
{
    std::vector<std::shared_ptr<T> > sharedptrs;

    for(unsigned int i=0; i<weakptrs.size(); ++i)
    {
        if (std::shared_ptr<T> temp = weakptrs.at(i).lock())
        {
            sharedptrs.push_back(temp);
        }
    }

    return sharedptrs;
}
template <class T>
struct isInvalid : public std::unary_function<T, bool>
{
    bool operator() (T rhs) { return !rhs.lock(); }
};

template <class T>
void EraseInvalid( std::vector<T>& targetlist )
{
    targetlist.erase( remove_if(targetlist.begin(), targetlist.end(), isInvalid<T>() ), targetlist.end());
}
下面是如何清除所有无效指针

template <class T>
std::vector<std::shared_ptr<T> > MassLock(const std::vector<std::weak_ptr<T> >& weakptrs)
{
    std::vector<std::shared_ptr<T> > sharedptrs;

    for(unsigned int i=0; i<weakptrs.size(); ++i)
    {
        if (std::shared_ptr<T> temp = weakptrs.at(i).lock())
        {
            sharedptrs.push_back(temp);
        }
    }

    return sharedptrs;
}
template <class T>
struct isInvalid : public std::unary_function<T, bool>
{
    bool operator() (T rhs) { return !rhs.lock(); }
};

template <class T>
void EraseInvalid( std::vector<T>& targetlist )
{
    targetlist.erase( remove_if(targetlist.begin(), targetlist.end(), isInvalid<T>() ), targetlist.end());
}

我认为最好的选择是使用弱指针容器。如果您的编译器由于某种原因不支持C++11或TR1,则在Boost中可用

当目标被破坏时,弱指针将自动失效,假设您正确初始化了对象

下面是一些示例代码,用于获取弱指针容器中的所有有效指针

template <class T>
std::vector<std::shared_ptr<T> > MassLock(const std::vector<std::weak_ptr<T> >& weakptrs)
{
    std::vector<std::shared_ptr<T> > sharedptrs;

    for(unsigned int i=0; i<weakptrs.size(); ++i)
    {
        if (std::shared_ptr<T> temp = weakptrs.at(i).lock())
        {
            sharedptrs.push_back(temp);
        }
    }

    return sharedptrs;
}
template <class T>
struct isInvalid : public std::unary_function<T, bool>
{
    bool operator() (T rhs) { return !rhs.lock(); }
};

template <class T>
void EraseInvalid( std::vector<T>& targetlist )
{
    targetlist.erase( remove_if(targetlist.begin(), targetlist.end(), isInvalid<T>() ), targetlist.end());
}
下面是如何清除所有无效指针

template <class T>
std::vector<std::shared_ptr<T> > MassLock(const std::vector<std::weak_ptr<T> >& weakptrs)
{
    std::vector<std::shared_ptr<T> > sharedptrs;

    for(unsigned int i=0; i<weakptrs.size(); ++i)
    {
        if (std::shared_ptr<T> temp = weakptrs.at(i).lock())
        {
            sharedptrs.push_back(temp);
        }
    }

    return sharedptrs;
}
template <class T>
struct isInvalid : public std::unary_function<T, bool>
{
    bool operator() (T rhs) { return !rhs.lock(); }
};

template <class T>
void EraseInvalid( std::vector<T>& targetlist )
{
    targetlist.erase( remove_if(targetlist.begin(), targetlist.end(), isInvalid<T>() ), targetlist.end());
}

如果需要对同一对象进行多个引用,则可能需要一个智能指针容器,如std::shared_ptr,或者如果没有C++11,则需要Boost提供的一个智能指针。

如果需要对同一对象进行多个引用,如果没有C++11,您可能需要一个智能指针容器,如std::shared_ptr或Boost中的一个。

按照锑的建议,使用弱_ptr更改列表以保存引用,并自动删除已破坏的元素,如下所示

首先,请澄清一些措辞:您的标题应该是C++容器,它在销毁时自动删除元素引用,因为删除元素实际上破坏了元素,因此您不希望在销毁时删除它,而是希望引用从容器中删除。p>

std::list<std::weak_ptr<Foo>> foos;

{
    // create a new entry in the container
    const auto& iter = foos.insert(foos.end(), std::weak_ptr<Foo>());
    // create an object of type "Foo" and store it in a shared_ptr
    std::shared_ptr<Foo> foo
        (new Foo
        // set a custom deleter that actually deletes the object
        // AND erases it from the container
        , [&foos, iter](Foo* ptr)
            {
                delete ptr;
                foos.erase(iter);
            }
        );
    // set the pointer to the element into the container
    *iter = foo;
}

// the shared_ptr "foo" ran out of scope;
// as there is no further strong reference to its object
// , the custom deleter was called which has removed the entry from the container
// so foos.size() is now 0

请注意,我将容器从vector更改为list,因为vector可能会使传递给自定义删除器的迭代器无效,请参阅,而list则不会。如果您想坚持使用向量,可以使用索引作为传递给自定义删除器的元素的引用,但是请注意,在结束之前向向量插入元素会损坏此引用。

按照锑的建议,使用弱ptr更改列表以保留引用,并自动删除已破坏的元素,如下所示

首先,请澄清一些措辞:您的标题应该是C++容器,它在销毁时自动删除元素引用,因为删除元素实际上破坏了元素,因此您不希望在销毁时删除它,而是希望引用从容器中删除。p>

std::list<std::weak_ptr<Foo>> foos;

{
    // create a new entry in the container
    const auto& iter = foos.insert(foos.end(), std::weak_ptr<Foo>());
    // create an object of type "Foo" and store it in a shared_ptr
    std::shared_ptr<Foo> foo
        (new Foo
        // set a custom deleter that actually deletes the object
        // AND erases it from the container
        , [&foos, iter](Foo* ptr)
            {
                delete ptr;
                foos.erase(iter);
            }
        );
    // set the pointer to the element into the container
    *iter = foo;
}

// the shared_ptr "foo" ran out of scope;
// as there is no further strong reference to its object
// , the custom deleter was called which has removed the entry from the container
// so foos.size() is now 0

请注意,我将容器从vector更改为list,因为vector可能会使传递给自定义删除器的迭代器无效,请参阅,而list则不会。如果要坚持使用向量,可以使用索引作为传递给自定义删除器的元素的引用,但请注意,在结束之前将元素插入向量可能会损坏此引用。

unique\u ptr可能就是您想要的。使用某种智能指针,可以很容易地在范围退出时销毁对象,正如其他人指出的那样。似乎很难自动更新foos,即在作用域出口处使其成为foos.size==0。事实上,我怀疑是否存在任何合理的解决方案,因为这需要智能指针知道它所在的容器。unique_ptr可能是您想要的。正如其他人所指出的,在范围退出时销毁对象很容易用某种智能指针完成。似乎很难自动更新foos,即在作用域出口处使其成为foos.size==0。我实际上怀疑是否存在任何合理的解决方案,因为它需要一个智能指针来知道它在什么容器中。