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

Recommended Answers

All 3 Replies

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;)).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.