Path: utzoo!utgpu!jarvis.csri.toronto.edu!torsqnt!lethe!becker!pantor!richard From: richard@pantor.UUCP (Richard Sargent) Newsgroups: comp.lang.c++ Subject: virtual destructors Message-ID: <45.UUL1.3#5109@pantor.UUCP> Date: 19 Jan 90 18:50:26 GMT Organization: Pansophic Systems Inc, Graphics Product Company Lines: 98 We have a problem which seems to require virtual destructors. Is such a thing valid in C++? If not, is there an alternative? Stroustrup's book doesn't get into this very deeply, so I hope some one out there can advise us. The general description of our problem follows. Thanks for any and all help. We have a base class called FORM and a class derived from it called GROUP. The derived class provides a group of FORM's. It is supposed to support nested GROUP's. That is where the problem arises. If I delete an item from a GROUP which is a FORM, everything works as desired. But if the object to be deleted is itself a GROUP, we would like to delete it as a GROUP not as a FORM. Remember the GROUP class is a list of the base class (FORM). If virtual destructors are valid, then we should be able to have a simple and elegant solution. If they are not, then I need to know how else I can solve this problem. The overall structure of the solution described above has some extremely desirable properties for us, so we would like to retain it as much as possible. We have come up with one workaround, a virtual function "deleteyourself()", but that is not nearly as nice as having things handled correctly and automatically from the destructors. A completely transposed solution (along the lines of the Smalltalk container classes) is acceptable, but not nearly as nice. example (any syntax errors are the result of transcribing the text): #include #include "gslist.h" // generic singly linked list, Stroustrup 7.3.2 typedef FORM* PFORM; ... struct FORM { char *id; FORM(char *name) { id = new char[strlen(name)+1]; strcpy(id, name); } // minor question: how well defined is the interaction between // the strdup() function and the above "new char" plus strcpy()? ... ~FORM() { if (id) delete id; } }; struct GROUP : FORM { gslist(PFORM) members; // group's member list GROUP(char *s) : (s) {} FORM *addmember(FORM *f) { members.append(f); return f; } GROUP *addmember(GROUP *g) { addmember((FORM *)g); return g; } ... ~GROUP() { PFORM fp; while (fp = members.get()) delete fp; } } ... main() { // // Create tree // // root // a1 // b1 // b1.1 // b1.2 // b1.2.1 // b1.2.2 // b1.3 // c1 // GROUP *root = new GROUP("root"); root->addmember( new FORM("a1") ); GROUP *b1 = root->addmember( new GROUP("b1") ); b1->addmember( new FORM("b1.1") ); GROUP *b1_2 = b1->addmember( new GROUP("b1.2") ); b1_2->addmember( new FORM("b1.2.1") ); b1_2->addmember( new FORM("b1.2.2") ); b1->addmember( new FORM("b1.3") ); root->addmember( new FORM("c1") ); delete b1; // Delete the subtree at b1. // This will not destroy b1.2.1 or b1.2.2 // because the base class destructor is used // to destroy b1.2 even though b1.2 is a group. } Richard Sargent Internet: richard@pantor.UUCP Systems Analyst UUCP: ...!mnetor!becker!pantor!richard