I recently ran into this problem at work. A library I'm using makes use of reference counted objects and implements its own way of handling it. Part of the implementation is that each class of the library has a private destructor. Im guessing this is to prevent creation of objects on the stack as the library manages objects lifetime automatically (Its a scene graph).
Anyways, I wanted to allocate an array of such a class on the heap and ran into the following problem:
#include <iostream>
using namespace std;
class test
{
public:
test() {
cout << "ctor" << endl;
}
//~test() = delete; also doesnt work
private:
~test()
{
cout << "dtor" << endl;
}
};
int main()
{
//works
auto oneInstance = new test;
//doesnt work
auto manyInstances = new test[3];
}
The array allocation produces the following error using GCC:
source_file.cpp: In function ‘int main()’:
source_file.cpp:15:5: error: ‘test::~test()’ is private
~test()
^
source_file.cpp:26:36: error: within this context
auto manyInstances = new test[3];
^
Why does the destructor need to be public/available in order to allocate an array of this class on the heap? It works fine when only allocating a single instance like in the line before. I also tried using the more modern "delete" syntax, but it produced the same result.
Is there any kind of magic in the new[] operator that I'm not aware of?
EDIT:
Thanks for the quick help. Im wondering why this code doesnt print "dtor" twice though:
#include <iostream>
using namespace std;
class test
{
public:
test() {
static int allocations = 0;
++allocations;
if(allocations == 3)
{
//produce exception
throw 1;
}
cout << "ctor" << endl;
}
~test()
{
cout << "dtor" << endl;
}
};
int main()
{
//works
auto oneInstance = new test;
//doesnt work
try {
auto manyInstances = new test[3];
}
catch(...)
{
cout << "error?";
}
}
This prints:
ctor ctor dtor error?