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...