Din destructor definition skal altid matche din constructor, dvs. du skal selv lave free af alle de objekter du allokerede. I fht. om nogle af din klasse's member variabler peger på andre objekter har det ingen betydning, hvis ikke du har allokeret dem vha. new i constructoren.
Mht. at "overloade" new og delete for at teste constructor/destructor så har du misforstået overloading begrebet - overloading af en funtion drejer sig om at have flere funktioner med SAMME navn, men forskellige parametre. Overloading sikrer så at compileren vælger den korrekte version i fht. de parametre du angiver. Derimod er det jo sådan at funktionen 'new' kalder klassens constructor, og funktionen delete klassens 'destructor' - måske er det det du mener.
Man overloader ofte constructoren til en klasse, sådan at man kan lave new til den på flere forskellige måder. I dit tree-node eksempel, kunne man forestille sig at man vill kontruere enten en node med to børn, eller en node helt uden. Man kunne så overloade (og her er der tale om overloading) constructoren:
TreeNode::TreeNode(TreeNode left, TreeNode Right) { setLeftChild(left); setRightChild(right); } // Constructor med parametre TreeNode::TreeNode(void) { // Anvend "laveste" contstrutor, dvs. den med flest parametre. TreeNode(NULL, NULL); } // Overloaded constructor UDEN parametre.
HUMLEN ER: Hvis du ikke selv laver new INDEN I CONSTRUCTOREN, skal du heller ikke lave delete i destructoren. I dit eksempel burde den være nok blot at skrive:
TreeNode node = new TreeNode(); : : // En masse behandling baseret på node : : delete node; /* Færdig med at bruge den. */
// Strengt taget ikke nødvendigt, da instansen af klassen jo forsvinder // når destructoren er kørt til ende, men jeg synes det ser pænt ud ... // og det forhindrer at ovenstående kan udføres to gange. theValue = NULL; theLength = 0; } // destructor
char * myString::getValue(void) { return theValue; } // getValue int myString::setValue(char *s) { int newLength = strlen(s) + 1; if (s > theLength) { // Gamle størrelse for lille til nye værdi - frigiv gamle storage // og allokér ny. delete[] theValue; theValue = new char(newLength); }; memcpy(theValue, s, newLength); } // setValue;
Det jeg hørte om overloading af new og delete var, at man kunne overloade metoden, så den kom med en udskrift, således man kunne følge med i allokering/deallokering...
Din destructor er forkert - du laver ikke new på hverken left eller right i din constructor - og dermed skal du heller ikke lave delete af dem i destructoren. Det du gør ovenfor er at slette hele grene med alle "blade" i det øjeblik du sletter noden. Det er muligvis også det du ønsker, men normalt vil man balancere træet ud fra den slettede nodes 'forældre' og bevare linken til alle "bladene".
En nem måde at balancere på er at lave right til ny forældre på den slettede nodes plads, og så lade left være første "barn" under denne node. (Ved at bruge right som forældre, sikre du at træet altid er "tungest" til venstre.)
For at overloade new og delete skal du jo lave nye versioner for alle de klasser du ønsker at følge med i allokering/deallokering for - så synes jeg måske det var nemmere blot at ændre i deres constructor/deconstructor så de selv kalder din logging funktion, når det er relevant.
så faktisk kan jeg nøjes med følgende destructor?!
TreeNode::~TreeNode(void) { left = NULL; right = NULL; }
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.