schmidt%blanche.ics.uci.edu@ORION.CF.UCI.EDU ("Douglas C. Schmidt") (10/10/88)
Hi,
The following program causes a segmentation fault when executed on
Sun 3's and 4's. The problem appears to be the virtual destructor:
virtual ~Node ( void ) .....
from class Node. When this is omitted the program works fine.
Readers of the Journal of Object-Oriented Programming will recognize
this as Andrew Koenig's ``dynamic binding'' example from the
August/September issue. This compiles and executes correctly when
compiled with CC.
----------------------------------------
#include <stream.h>
class Node {
friend class Tree;
friend ostream& operator << ( ostream&, const Tree& );
private:
int Use;
protected:
Node ( void ) {
Use = 1;
}
virtual void Print ( ostream& ) {
}
virtual ~Node ( void ) { // if this is commented out the program runs ok
}
};
class Tree {
private:
friend class Node;
friend ostream& operator << ( ostream&, const Tree& );
Node *Ptr;
public:
Tree ( int );
Tree ( char *, Tree );
Tree ( char *, Tree, Tree );
Tree ( const Tree& T ) {
Ptr = T.Ptr; ++Ptr->Use;
}
~Tree ( void ) {
if ( --Ptr->Use == 0 ) {
delete Ptr;
}
}
void operator = ( const Tree& T ) {
++T.Ptr->Use;
if ( --Ptr->Use == 0 ) {
delete Ptr;
}
Ptr = T.Ptr;
}
};
ostream& operator << ( ostream& Stream, const Tree& T ) {
T.Ptr->Print ( Stream );
return ( Stream );
}
class Int_Node : public Node {
friend class Tree;
private:
int Num;
Int_Node ( int K ): Num ( K ) {
}
void Print ( ostream& Stream ) {
Stream << Num;
}
};
class Unary_Node : public Node {
friend class Tree;
private:
char *Operator;
Tree Operand;
Unary_Node ( char *Op, Tree T ): Operator ( Op ), Operand ( T ) {
}
void Print ( ostream& Stream ) {
Stream << "(" << Operator << Operand << ")";
}
};
class Binary_Node : public Node {
friend class Tree;
private:
char *Operator;
Tree Left;
Tree Right;
Binary_Node ( char *Op, Tree T1, Tree T2 ):
Operator ( Op ), Left ( T1 ), Right ( T2 ) {
}
void Print ( ostream& Stream ) {
Stream << "(" << Left << Operator << Right << ")";
}
};
Tree::Tree ( int Num ) {
Ptr = new Int_Node ( Num );
}
Tree::Tree ( char *Op, Tree T ) {
Ptr = new Unary_Node ( Op, T );
}
Tree::Tree ( char *Op, Tree T1, Tree T2 ) {
Ptr = new Binary_Node ( Op, T1, T2 );
}
main () {
Tree T = Tree ( "*", Tree ( "-", 5 ), Tree ( "+", 3, 4 ) );
cout << T << "\n";
T = Tree ( "*", T, T );
cout << T << "\n";
}
----------------------------------------