LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-13-2011, 04:13 AM   #1
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Destructor called on objects in deque without it being called explicitly


I feel there's a bit of a misunderstanding going on between C++ and me...

My problem is that I have a deque of pointers to a class, and create objects then add them to the deque in a for loop. However, the destructor is called on the object as soon as the loop quits.

Code:
#include <deque>
#include "stdio.h"

class Test {
    private:
        static int number;
        int id;
     public:
        Test(void);
        Test(const Test&);
        ~Test(void);
};
 
int Test::number = 0;

Test::Test(void){
    id = ++number;
    printf("Creating number %d\n",id);
}

Test::Test(const Test& old){
    id = old.id;
    printf("Copying number %d\n",id);
}

Test::~Test(void){
    printf("Deleting number %d\n",id);
}

int main(void){
    std::deque<Test*> myDeque;
    int i;
    for(i=0;i<5;i++){
        printf("\ni is now %d\n",i);
        Test temp;
        myDeque.push_front(&temp);
    }
    printf("Out of loop\n\n");
    return 0;
}
This prints:

Code:
i is now 0
Creating number 1
Deleting number 1

i is now 1
Creating number 2
Deleting number 2

i is now 2
Creating number 3
Deleting number 3

i is now 3
Creating number 4
Deleting number 4

i is now 4
Creating number 5
Deleting number 5
Out of loop
Now, if I change the deque from deque<Test*> to deque<Test> then it works fine - I get:

Code:
i is now 1
Creating number 1
Copying number 1
Deleting number 1
...
Out of loop
...
Deleting number 5
Deleting number 4
...
Deleting number 1
However, I can't do this with my actual code, because I am creating a deque of pointers to an abstract class, so it won't let me instantiate the class. (This is all so that I can take advantage of polymorphism, and call functions on a set of similar objects without worrying what type of object I'm dealing with).

So, I suppose my question is: what is the correct way to create that deque of pointers to the abstract class? I don't seem to be barking up the right tree currently.

Thanks in advance
 
Old 07-13-2011, 05:18 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,539

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
You've declared a local object in your for-loop, which gets destroyed with each iteration of the loop.
Code:
Test temp;
If you want the objects to persist beyond the scope of the loop, then do something like:
Code:
Test* temp = new Test;
myDeque.push_front(temp);
P.S. Don't forget to delete the allocated object(s) at a later time.

Last edited by dwhitney67; 07-13-2011 at 05:20 AM.
 
1 members found this post helpful.
Old 07-13-2011, 06:58 AM   #3
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Arch
Posts: 1,632

Original Poster
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Brilliant, thank you very much.

With regards to your postscript, do you just mean that when popping the objects I should do:

Code:
delete mydeque.back();
mydeque.pop_back();
Or do I need to do something more to ensure they are deleted correctly?
 
Old 07-13-2011, 07:11 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,539

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Snark1994 View Post
Brilliant, thank you very much.

With regards to your postscript, do you just mean that when popping the objects I should do:

Code:
delete mydeque.back();
mydeque.pop_back();
Or do I need to do something more to ensure they are deleted correctly?
What you have above is fine; however don't you want to have a handle to the Test object to do something with it?
Code:
Test* test = mydeque.back();
mydeque.pop_back();

// do something with test
...

delete test;

Last edited by dwhitney67; 07-13-2011 at 07:14 AM.
 
Old 07-13-2011, 08:05 AM   #5
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Arch
Posts: 1,632

Original Poster
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Yes, sorry, I just meant for how I go about deleting the object. Thankyou

However, it turns out there's an additional complication due to the fact that I'm using an abstract class.

Code:
#include <deque>
#include "stdio.h"

class MetaTest {
        public:
                virtual void something(void)=0;
};

class Test: public MetaTest {
        private:
                static int number;
                int id;
        public:
                Test(void);
                Test(const Test&);
                ~Test(void);
                void something(void){};
};

int Test::number = 0;


Test::Test(void){
        id = ++number;
        printf("Creating number %d\n",id);
}

Test::Test(const Test& old){
        id = old.id;
        printf("Copying number %d\n",id);
}

Test::~Test(void){
        printf("Deleting number %d\n",id);
}

int main(void){
        std::deque<MetaTest*> myDeque;
        int i;
        for(i=0;i<5;i++){
                printf("\ni is now %d\n",i);
                Test* temp = new Test;
                myDeque.push_front(temp);
        }
        printf("Out of loop\n\n");

        printf("Starting to delete:\n");
        while(myDeque.size() > 0){
                delete myDeque.back();
                myDeque.pop_back();
        }
        return 0;
}
My guess is that because I'm using a pointer to the MetaTest class, it doesn't know it has to call the Test destructor. Is there a way around this? Or do I have to write another virtual method in the MetaTest called "deleteMe()" which is then overridden in each of the derived classes and called before I delete the object?

EDIT: Never mind. For others asking the same question, read this article on virtual destructors. I fixed it by adding a "virtual ~MetaTest(void)" declaration and defining it as "MetaTest::~MetaTest(void) { }"

Thanks again,

Last edited by Snark1994; 07-13-2011 at 08:10 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how is it called - what is it ? baxy77 Linux - Server 1 08-10-2009 06:46 AM
This might as well be called 12.0 RC2! onebuck Slackware 17 06-26-2007 10:17 PM
Changing the (what is it called?) freakin'me Linux - General 8 10-06-2005 04:00 AM
What are these called and where to get?? TippyToes Linux - Software 2 01-20-2005 03:38 PM
what's this called? ph33r Linux - General 1 04-19-2002 11:56 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:02 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration