Hi All,
Here i am with another question . When i execute the code below the destructor in Stone is called twice . Why?
In main set<Stone> stones = bag.letMeSeeStones(); is coming from reference hence "stones" should not be treated like a local object.

#include <iostream>
#include <set>
using namespace std;

class Stone{
public:
        Stone(const double mg):weight(mg){}
        friend bool operator<(const Stone &s1,const Stone &s2) {
                return s1.weight <s2.weight;
        }
        ~Stone(){
        cout << " I am no more a stone " <<endl;
        }
private:
double weight;

};

class BagOfStone{
public:
        void keepStone(const Stone &stone){
                stones.insert(stone);
        }
        set<Stone>& letMeSeeStones(){
                return stones;
        }
private:
        set<Stone> stones;
};

int main(int argc,char** argv){
        BagOfStone bag;
        Stone *heavyone = new Stone(10.0);
        bag.keepStone(*heavyone);
        set<Stone> stones = bag.letMeSeeStones();
        return 0;
}

If want to achieve my goal than i can modify like this

#include <iostream>
#include <set>
using namespace std;

class Stone{
public:
        Stone(const double mg):weight(mg){}
        friend bool operator<(const Stone &s1,const Stone &s2) {
                return s1.weight <s2.weight;
        }
        ~Stone(){
        cout << " I am no more a stone " <<endl;
        }
private:
double weight;

};

class BagOfStone{
public:
        void keepStone(const Stone &stone){
                stones.insert(stone);
        }
        set<Stone>* letMeSeeStones(){
                return &stones;
        }
private:
        set<Stone> stones;
};

int main(int argc,char** argv){
        BagOfStone bag;
        Stone *heavyone = new Stone(10.0);
        bag.keepStone(*heavyone);
        set<Stone> *stones = bag.letMeSeeStones();
        return 0;
}

I hope there would not be any difference in the behavior of above two program. I would appreciate if any one can explain why there should be difference and what could be repercussion if there would not be any difference in behavior.

Thanks,
Shailendra

The std::set is an intrusive container: it has its own copies of inserted elements. So the program creates three incarnations of class Stone: one obtained from new op and the 2nd allocated in the container member and the 3rd in stones variable . The 1st object does not deleted (you have memory leak). That's why Stone destructor called twice by set<Stone> objects.

The 2nd snippet does the same thing.

If you want to create the only Stone object, declare std::set<Stone*>. I don't think it's the better solution. It's hard work to manage a set of pointer referenced objects: which of them were dynamically allocated?..

When i run the second snippet it calls destructor only once but in case of 1st snippet it calls it twice.

Oh, yes... No 2nd set<Stone> in the 2nd snippet, but dynamically created Stone object does not deleted too...
It's a very bad practice (or common error;)).

This article has been dead for over six months. Start a new discussion instead.