Graeme.Dixon%newcastle.ac.uk@NSS.CS.UCL.AC.UK (Graeme Dixon) (04/11/89)
Even though a class contains private constructors and destructors, g++ allows instances of the class to be declared. The following program illustrates the bug: #include <stream.h> class A { friend class B; int no_refs; int inc_ref_count() { return ++no_refs; } int dec_ref_count() { return --no_refs; } A() { cout << "A::A\n"; } ~A() { cout << "A::~A\n"; } public: int get_ref_count() { return no_refs; } }; class B { A *ptr; public: B() { cout << "B::B\n"; ptr = (A *) 0; } ~B() { cout << "B::~B\n"; if (ptr && ptr->dec_ref_count() == 0) delete ptr; } void operator=(A* a) { if (ptr && ptr->dec_ref_count() == 0) delete ptr; ptr = a; ptr->inc_ref_count(); } A* operator->() { return ptr; } }; main() { // this is okay... B b; b = new A; cout << b->get_ref_count() << "\n"; // ...until here which shouldn't compile A a; // the constructor for A isn't called // but the destructor is when the scope ends cout << a.get_ref_count() << "\n"; // returns an incorrect value A *a1 = new A; // constructor called cout << a1->get_ref_count() << "\n"; // value returned okay delete a1; } Using g++ version 1.34.0 on a Sun 3/60M (OS 4.0.1) the above program (compiled using g++ -o cons_bug cons_bug.cc) produces: B::B A::A 1 47412 A::A 0 A::~A A::~A B::~B A::~A Graeme Dixon - Computing Laboratory, University of Newcastle upon Tyne, UK JANET = Graeme.Dixon@uk.ac.newcastle ARPA = Graeme.Dixon@newcastle.ac.uk UUCP = ...!ukc!newcastle.ac.uk!Graeme.Dixon PHONE = +44 91 222 8067 PS. Thanks for the overloaded delete bug fix...