CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2002
    Posts
    5,757

    Pointer Elements & STL Containers :: STL

    Hi.

    Do delete STL functions such as remove() and erase() calls a class destructor if the element is a pointer to an object? For example, consider a vector of pointers to ClassX objects and a list of pointers to ClassX objects..



    code:--------------------------------------------------------------------------------
    std::vector<ClassX *> sTextVec;

    ClassX *pCX;

    sTextVec.push_back(pCX);
    ...
    // Now you need to deallocate memory from pText.
    // Do functions such as remove() and erase() call ClassX
    // destructor, or do you have to delete them explicitly?
    --------------------------------------------------------------------------------


    Thanks,
    Kuphryn

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    You need to call the destructor of ClassX yourself.

    Item 7 of Scott Meyers , Effective STL :

    "When using containers of new'ed pointers, remember
    to delete the pointers before the container is destroyed".


    You can use various smart pointers, such as Boost's shared_ptr
    or the CountedPtr from the Josuttis book - they will automatically
    do the delete for you.

    However, you can not use the C++ auto_ptr ... (they do not
    meet the requirements for elements of standard containers -
    namely, after a copy or assignment of an auto_ptr, source and
    sink are not equivalent.

  3. #3
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968
    You can use the DeleteObject class I have listed below for deleting pointers from a container.

    The example below list several methods that work in conjunction with erase and remove_if.


    #include <string>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <functional>

    using namespace std;

    class DeleteObject
    {
    public:
    template<typename T>
    operator()(T& ptr)
    {
    delete &*ptr;
    ptr = NULL;
    return true;
    }
    };

    class foo
    {
    public:
    foo(const string Name):m_Name(Name)
    {
    }
    ~foo()
    {
    cout << "Deleting " << m_Name << endl;
    }
    bool DeleteIfEq(const std::string &TestStr) const {return (TestStr == m_Name);}
    typedef bool (TestFuncName)(const std::string &);
    typedef int fooint;
    string m_Name;
    };


    template<typename TestObj>
    class DeleteOnMemberFunc_DeleteIfEq
    {
    public:
    DeleteOnMemberFunc_DeleteIfEq(const TestObj& testobj) : m_testobj(testobj){}
    template<typename T>
    bool operator()(T& ptr)
    {
    if (ptr->DeleteIfEq(m_testobj))
    {
    delete &*ptr;
    ptr = NULL;
    return true;
    }
    return false;
    }
    const TestObj& m_testobj;
    };


    template<typename T>
    bool DeleteAndNullifyIterator(T *& pObj)
    {
    delete pObj;
    pObj = NULL;
    return true;
    }

    bool TestFoo(foo *&MyFoo)
    {
    if (MyFoo->m_Name == "Deleteme")
    {
    return DeleteAndNullifyIterator(MyFoo);
    }
    return false;
    }

    class comp
    {
    public:
    comp(string& _t): t(_t) {}

    template<class T>
    bool operator()(T& pt)
    {
    if(pt->m_Name == t)
    {
    delete pt; return true;
    }
    return false;
    }

    public:
    string &t;
    };

    int main(int argc, char* argv[])
    {
    const char Items[][32] = {"One", "RemoveMe", "Deleteme", "RemoveMe", "Two", "Deleteme", "Three", "Deleteme", "Four", "RemoveMe"};
    vector<foo*> Foos;
    for( int i = 0;i < sizeof(Items)/32;i++)
    {
    Foos.push_back(new foo(Items[i]));
    }
    vector<foo*>::value_type x = new foo("Foo");
    Foos.push_back(x);
    cout << Foos.size() << endl;

    Foos.erase(remove_if(Foos.begin(), Foos.end(),comp(string("Deleteme"))), Foos.end());
    cout << Foos.size() << endl;

    Foos.erase(remove_if(Foos.begin(), Foos.end(),DeleteOnMemberFunc_DeleteIfEq<string>("RemoveMe")), Foos.end());
    cout << Foos.size() << endl;

    Foos.erase(remove_if(Foos.begin(), Foos.end(),DeleteObject()), Foos.end());
    cout << Foos.size() << endl;

    system("pause");
    return 0;
    }

    template<class Pred>
    class DeleteObject_If
    : public unary_function<Pred::first_argument_type,
    Pred::result_type> {
    public:
    DeleteObject_If(const Pred& pr, const Pred::second_argument_type y);
    result_type operator()(const argument_type& x) const;
    protected:
    Pred op;
    Pred::second_argument_type value;
    };
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  4. #4
    Join Date
    Feb 2002
    Posts
    5,757
    Okay. Thanks.

    I understand now from other responses and yours that STL containers do not deallocate memories that pointers point to. We have to deallocate explicitly.

    Kuphryn

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured