dmg@ssc-vax.UUCP (David Geary) (05/31/89)
I need some help. In the process of learning C++ for use on a project, I am developing some "basic" classes. First of all, I developed a string class, and then I went on to developing a "list" class. I've included some of the code from my .hxx file: ////////////////////////////////////////////////////////////////////////////// // LISTCLASS.HXX: // // // // This file defines three objects: // // // // I Class link: // // // // links are primitive objects which have only a constructor and the // // ability to print out the information contained in them. Each // // link has next and prev(ious) pointers which point to other // // links in a list. // // // // II Class list: // // // // lists are objects which manage a list of links. Each list // // contains pointers to the first and last links in the list, and // // also a count of the total number of links in the list at any // // given time. lists have the ability to insert links, get links // // from the list, or unlink links from the list. A list can also // // print information about itself, or show info on each of the // // links in the list. // // // // lists have the following operators overloaded: // // // // += Given a pointer to a link, the link is appended to the list. // // // // += Given a reference to a link, the link is appended to the list. // // // // -- Chops the last link off the node (unlinks it). Note // // That a pointer to the link removed is returned. // // // // [] Returns a reference to a specified link (as though the // // list were an array). // // // ////////////////////////////////////////////////////////////////////////////// #ifndef LIST_CLASS #define LIST_CLASS //=============================== Class link ===============================// class link { friend class list; // A list can access private parts of a link. friend class list_iterator; // list_iterators need to access links too. link *next; // The next link in the list. link *prev; // The previous link in the list. public: link() { prev = next = NULL; } // Constructor: link x; virtual void print() { cout << form("Addr = %ld\nNext = %ld\nPrev = %ld\n\n", this,next,prev); } }; //=============================== Class list ===============================// class list { friend class list_iterator; // a list_iterator can access list's privates. protected: int num_links; // num links on list at any given time. link* first; // first link on list. link* last; // last link on list. public: list() { num_links = 0, first = last = (link*)NULL; } BOOLEAN insert (link& lnk, int pos); // Insert lnk at pos in list. link* getp (int pos); // Get Pointer to specified link. link& getr (int pos); // Get Reference to spec. link. link* unlink (int pos); // Unlink specified link. void shownodes (); // Print link info for links. virtual void print (); // Prints private data of list. BOOLEAN list::operator+=(link& lnk) { return insert(lnk,num_links+1); } BOOLEAN list::operator+=(link* lnk) { return insert(*lnk,num_links+1); } link* list::operator--() { return unlink(num_links); } link& list::operator[](int pos) { return getr(pos+1); } }; #endif Ok? So then, any instance of a class which is derived from link can be used as a link, and appended to a list: class string : public link { // a bunch of stuff... }; main() { list mylist; string s1, s2, s3; mylist += s1; mylist += s2; mylist += s3; mylist.print(); mylist.shownodes(); } This works just fine. However (finally getting to the problem), I'd like to be able to have a list of dynamically allocated links, so I derived the following class from list: class dlist : public list // "dynamic" list... { public: dlist() { num_links = 0; first = last = (link*) NULL; } ~dlist() { int i=num_links; while(i-- >= 0) delete getp(i); } }; Now I can do things like: class string : public link { // same bunch of stuff as above... }; main() { dlist my_dlist; my_dlist += new string; my_dlist += new string; my_dlist += new string; my_dlist.print(); my_dlist.shownodes(); } Ok, this works too - sort of. The problem is that in the example using a "list", the destructors for s1, s2 and s3 are called. However, in the example using "dlist", no destructors are called for the instances of strings that get appended onto the list. Notice that the dlist destructor calls delete to free the memory associated with each string, but the explicit destructor for strings is not called. Any suggestions? -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, Seattle ~ ~ "I wish I lived where it *only* rains 364 days a year" ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vasta@apollo.COM (John Vasta) (06/03/89)
In article <2685@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: > > I need some help. In the process of learning C++ for use on a project, >I am developing some "basic" classes. First of all, I developed a string >class, and then I went on to developing a "list" class. I've included some >of the code from my .hxx file: > > [code example deleted] > > Ok, this works too - sort of. The problem is that in the example using >a "list", the destructors for s1, s2 and s3 are called. However, in >the example using "dlist", no destructors are called for the instances >of strings that get appended onto the list. Notice that the dlist destructor >calls delete to free the memory associated with each string, but the >explicit destructor for strings is not called. > > Any suggestions? Sounds like you've tuned in recently - you may have missed the big virtual destructor discussion. Yes, destructors can be declared virtual (in recent implementations, at least). Your dlist destructor only knows that it's destroying an object pointed to by a link*, and the link class has no destructor, so there's nothing to do. Declare a virtual destructor in the link class, and then classes derived from link will have their destructors called when deleting via a ptr-to-link. -- John Vasta Apollo Computer, Inc. vasta@apollo.com M.S. CHA-01-LT (508) 256-6600 x6362 330 Billerica Road, Chelmsford, MA 01824 UUCP: {decwrl!decvax, mit-eddie, attunix}!apollo!vasta