views:

265

answers:

8

For example is this correct:

class C 
{
   private: 
     C();
     C(const & C other);
}

or you should rather provide definition(s):

class C 
{
   private: 
     C() {};
     C(const & C other) {};
}

? Thanks for the current answers. Let's extend this question - does compiler generate better code in one of this examples? I can imagine that providing body for ctor forces compiler to include some (empty) code in compilation unit? Is this also true for auto-generated code?

A: 

If you use the 'empty' declaration, the compiler will no longer generate the default implementation and you will get link errors. If you declare them, you have to write them so the empty-brace form is necessary.

Jeff Paquette
That's not true, you won't get link errors if you don't call these constructors.
Paul
Ah. correct, if there are other constructors defined. There were not in the OP's code.
Jeff Paquette
A: 

You will need to provide definitions. If you do not, and you attempt to use them, it will fail to link.

Alex Deem
Note that this constructors are private and assume that they won't be used by class itself.
doc
I consider this to be a feature. If I do not wish anyone to make a copy -- either clients of my class or even myself -- then I want the compiler to tell me off when I try to do so.
Kaz Dragon
Ignore me, I failed to realise they were private... :)
Alex Deem
A: 

That depends on whether you use these constructors or not. If you don't use them you may leave them undefined. If you use them (for example you are creating objects of the class from static functions of class, you need to define them) you need to provide definitions, otherwise you'll get unresolved external symbols error from linker.

Paul
+4  A: 

You may use declaration-only constructors to disallow given constructions, like standard construction, or copy-construction.

For example, if you want to avoid your object being copied you can declare as private the copy-constructor and the assignment operator and do not define them, then anyone,including you, who tries to copy the object will have linker errors.

About your last edit: I'd expect a decent compiler to produce the same code for a default constructor and for an empty constructor and no initialization list, in the end, what it needs to do is default-initialize each member.

Arkaitz Jimenez
You mean compiler errors, not linker errors.
doc
Arkaitz Jimenez
When constructor is declared private it won't compile, unless you are using singleton.
doc
Wrong, it will compile if you call it from the inside, it doesn't need to be a singleton, you may have several static methods that produce one or more objects of your class with a private constructor.
Arkaitz Jimenez
Assume they are not intended to be called from inside the class. In such case my question would be a nonsense.
doc
If they are intended to be called **and** you have declared them at all then you need to define them, you can't declare them and expect the compiler to generate a default constructor, it won't.
Arkaitz Jimenez
They are NOT intended to be called.
doc
Then just declare them as private.
Arkaitz Jimenez
And in this example are they declared public?
doc
I'm not saying they are, you just wrongly corrected me about the errors and the thread lead to this, I didn't say anything incorrect.
Arkaitz Jimenez
If they are declared as private, then you won't get linker errors because compiler will trigger errors first. The only case when this could compile is when calling them from inside the class. But then my example makes no sense, so it is obvious to assume that they are not intended to be called from inside the class.
doc
+8  A: 

If you do not wish your object to be copyable, then there is no need to provide the implementation. Just declare the copy ctor private without any implementation. The same holds for other ctors, if you do not want any body to use them, just declare them private without any implementation.

Naveen
+2  A: 

If you declare them without providing implementation, then you can't use them because they don't exist. If you want to use the constructors, you must either allow the compiler to create them by not declaring them, OR you must declare them and provide an implementation.

It is occasionally useful to provide a declaration but no implementation for a constructor that you don't want used. This is often done with the copy constructor for objects (such as singletons) that you don't want there to be copies of, ever. In such cases, the declaration is often made private as well.

Michael Kohne
+9  A: 

It is fine as long as you don't use them.

With the 0x standard you can use deleted functions.

class X {
   // ...
   X& operator=(const X&) = delete; // Disallow copying
   X(const X&) = delete;
};
fnieto
Thanks I would like to accept your answer as well but it's not possible and Naveen was first.
doc
+1  A: 

Firstly, if you want to make your class completely non-copyable, don't implement the private copy constructor and assignment operator. Otherwise it is still possible that a piece of code that has access (a method or a friend) can silently make copies. Without the implementation, you'll get a linker error.

However, a compiler error would be preferable, as you'll find out about the error faster. For this there's boost::noncopyable, or you can derive from a base class that hides its copy constructor and assignment operator.

Concerning the default constructor: the compiler will not generate one if you declare any constructor at all. There's generally no need to hide that specifically.

UncleBens
Thanks, this is really nice answer. So far I was using Java a lot, learning many OOP concepts with her, and probably she impressed a stamp on mind XP
doc