简体   繁体   中英

Destructor and smart pointers giving C2541

I'm trying to use some vectors of shared_ptr in my program, but doing so gives me a C2541-error: "delete": objects that are no pointers can't be deleted. I figured out it has something to do with the destructors of my classes (at least with one of them...) so i tried changing them - without success :( My application contains a class A, which holds two vectors: one of shared_ptrs to objects of class B and of shared_ptrs to objects of class A. Here are some parts of my code:

//A.cpp
A::~A(void)
{
    for(std::vector<BPtr>::iterator it = allBs.begin(); it != allBs.end(); ++it) 
    {   //loop that deletes all Bs
        delete it->get();
    }

    for(std::vector<APtr>::iterator it = allAs.begin(); it != allAs.end(); ++it) 
    {    //loop that (should) delete all As (and their As and Bs)
        delete it->get();
        delete it.operator*;
    }
}

//A.h
class A
{
public:
typedef std::shared_ptr<A> APtr; 
typedef std::shared_ptr<B> BPtr; 
// some more stuff
private:
std::vector<BPtr> allBs;
std::vector<APtr> allAs;
}

I'm getting the error twice: one comes from the line delete it.operator*; and the other one is caused inside of memory.h. I first had an extra recursive function which deleted the tree and was called by the destructor, but after a little thinking I thought that calling "delete" inside the destructor (line "delete it->get();") would do just the same.

You're doing it wrong.

The entire purpose of smart pointers like std::shared_ptr is that you do not have to manually delete what they point at. Indeed, you must not delete it manually. The smart pointer assumes ownership of the pointee—it will delete it itself when applicable. For std::shared_ptr , "when applicable" means "when the last std::shared_ptr pointing to the object is destroyed."

So just remove the destructor altogether, you don't need it. When the vectors are destroyed, they will destroy all of the contained std::shared_ptr s. This will reduce the reference count of the pointees. If any go to zero, they will be delete d automatically (by the shared_ptr destructor).

You can and must delete only things created with new . Only these exactly once, nothing else. Deletion can be done either "by hand" or by letting a smart pointer like std::shared_ptr do it for you (which is a very good idea). When using smart pointers, you can (and should) get rid of the new in favor of std::make_shared or std::make_unique .

The same applies to new[] and delete[] .

This means that in your destructor there is no room for delete because you never new ed anything and have it owned by a raw pointer (which was good).

You don't want to delete a shared_ptr 's contents, that's its job. simply reset the smart pointer:

it->reset();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM