can't fix the following error : "no appropriate default constructor available"

Started by
6 comments, last by dmatter 15 years, 9 months ago
I have to make a class which should be instantiated only with the new operator, so I declared the copy constructor and assign operator as private. However I can't instantiate the class in any way... so I searched a code specificly dealing with this, but it won't compile either. Here is a little code:


class thing {
    private:
	thing& operator = (const thing& other) {/* do nothing */}
	thing (const thing & other) {/* do nothing */}

    public:
	int a;
};

int main()
{

thing *object = new thing();// <--- ERROR C2512: 'thing' : no appropriate default constructor available


return 0;
}

Can anybody point out what am I doing wrong? Thanks in advance!!!
Advertisement
Since you have provided a copy constructor and an operator = you have to provide the default constructor. I believe the rule is something like, if you provide any of them, the compiler can't create the others.

Correct me where i'm wrong Si Crane.
If you do not specify any constructor, your compiler will create a default constructor, and a copy constructor for you. Because you have created a copy constructor, your compiler won't create a default constructor because it assumes that you intentionally do not want construction calls without a parameter to work.

You basically need to create a public constructor like this:

thing() {}


Sorry if the description is vague I have a bad migraine, perhaps someone else can explain more clearly.
Member of the NeHe team.
You have to provide a default constructor yourself.
If you don't provide any constructors then the compiler will automatically implement public default and copy constructors for you.

Of course, then there's nothing there preventing someone allocating an instance on the stack.
The gist of the issue is that by defining a constructor (the copy constructor you made private) you disabled the automatic generation of the default constructor. You can of course simply define it by hand as having an empty body, and everything will be fine.

A few comments about your code in general:
  • Making a class only instantiable with new is rarely a good idea. Unless this is for an assignment, I'd seriously consider changing the design to keep in line with the language.
  • What you are trying to do won't work, since it will not prevent creation of the object on the stack using the default constructor. Also, it will not prevent using placement new to create the object on stack memory either. A typical way to achieve this is to use a Factory pattern to create the object and make all constructors private.
  • You don't have to provide a body for your copy constructor and assignment operator. This way, if you ever attempt to use them, the linker will encounter an error because they are not defined.
Aha, I understand now, I was expecting that the default constructors will be generated in all conditions.

Thanks guys, for the quick response :)
Isn't the problem that you're doing:
thing *object = new thing();

instead of:
thing *object = new thing;

?
One explicitly default initialises and one doesn't.
The difference is actually more subtle than that though, see SiCrane's explanation.

This topic is closed to new replies.

Advertisement