tags:

views:

973

answers:

10

Hi,

I wanted to know Why compiler provides default copy constructor..Whats the strategy behind that idea.

Thanks in Advance.

+1  A: 

Saving you time? If you have a simple class (ie if you can easily copy construct all its elements) you then don't need to write one.

Goz
A: 

I'm not sure what the "official line is" (don't have Strastroup's book near me) and I'm sure someone will dig it up.

However, in most cases shallow copies and default initialization is "good enough", so it's better for the compiler to provide them than to have the developerexplicitly write them.

If the developer wrote this trivial copy constructors and the fields later change, it is up to that user to make the changes and there could be serious errors if he forgets (e.g., what are these fields constructed as?).

By only having users write copy constructors when there really is a need to do something fancy (like deep copying), you reduce the frequency of these errors.

Uri
+4  A: 

Because otherwise, when you pass an instance by value, how could the compiler generate one?

Stefano Borini
You could have the compiler complain about the lack of a copy constructor, I suppose.
Uri
Then I think you would have some backward compatibility issues. A class and a struct are similar. In C++, a struct is nothing but a class with methods and attributes public by default. This means that when you declare a struct from a C program compiled as a C++ one, there's an implicit copy constructor that you have to assume it's there for backward compatibility. Move this to classes, and you have the situation we know.
Stefano Borini
You could say that once any ctor is defined, a copy ctor isn't provided by default anymore. This would still be compatible with C.
Johannes Schaub - litb
Stroustrup could have defined an additional difference between class and struct, in that struct has a default copy ctor and class doesn't. Too late for that now though.
Mark Ransom
+3  A: 

I don't know why it was originally designed that way. But as a user I can say why I'm glad they did.

  1. If you use all RAII or POD types, a copy constructor will do the right thing
  2. Copy constructors don't require thinking or maintenance, they just work given #1

I feel the same way about the default assignment operator. Most people either a) define their copy constructor / equals operator incorrectly or fail to maintain it. I've removed a lot of bugs in C++ code by switching to RAII types and deleting hand coded operators / copy constructors.

JaredPar
+20  A: 

From a related (but not same) question - http://stackoverflow.com/questions/217911/why-dont-c-compilers-define-operator-and-operator/218713#218713:

Stroustrup said this about the default copy constructor in "The Design and Evolution of C++" (Section 11.4.1 - Control of Copying):

I personally consider it unfortunate that copy operations are defined by default and I prohibit copying of objects of many of my classes. However, C++ inherited its default assignment and copy constructors from C, and they are frequently used.

So the answer is that it was included reluctantly by Stroustrup for backwards compatibility with C (probably the cause of most of C++'s warts, but also probably the primary reason for C++'s popularity).

For my own purposes, in my IDE the snippet I use for new classes contains declarations for a private assignment operator and copy constructor so that when I gen up a new class I get no default assignment and copy operations - I have to explicitly remove the declaration of those operations from the private: section if I want the compiler to be able to generate them for me.

Michael Burr
a base class such as boost::noncopyable achieves the same thing more succinctly
Phil Nash
I would best like it like this: Providing a default ctor by default, but only if there is no other ctor. If there is, one can do `= default` like Richard shows for c++0x, and have still good performance. What do you think about it?
Johannes Schaub - litb
@Phil - I agree, but my snippet currently still uses the 'old-fashioned' method because of inertia/laziness (of the ain't really broke, so no effort goes into fixing variety) and it has no dependecies. Using a private noncopyable base class means the .cpp file needs to #include "noncopyable.h". Might not be a great excuse, but it's what I have. Note that I do often clean this up to use a noncopyable base, because I do think it's a better way. I really should fix my snippet.
Michael Burr
@litb -are you talking about the default ctor or the compiler generated copy ctor? My understanding of C++0x is that that what you're describing will be the behavior for default ctors. Copy ctors will still be generated automatically if needed unless explicitly disabled (using one of the existing techniques or using the `delete` keyword). I imagine that there is too much existing code that depends on this to make a more radical change possible. Then again, I'm no C++0x expert, so I might just plain be wrong.
Michael Burr
oh i'm sorry i meant "copy ctor" -.-
Johannes Schaub - litb
@litb: I'm not sure what reason there would be against your idea that auto-genned copy ctors are disabled when there's any explicitly defined ctor (like the default ctor is in that case). I can't think of a reason off the top of my head. Obviously it would be difficult/impossible to do at this point, but it might have been a good middle ground if it had been done initially...
Michael Burr
+1  A: 

If you have a struct being used by C code, a default copy constructor needs to be there to preserve C struct copying semantics.

Paul Nathan
A: 

I think you're coming at it from the wrong direction - if the compiler could write a complete and correct 'default' copy constructor for every class or structure, then nobody would complain, would they? The trouble is, the compiler can't do that reliably, so for those cases you need to write your own, overriding the default.

njplumridge
+3  A: 

A few points:

It's important to be able to control if an object can or cannot be copied.

If you don't want that an object can be copied, then you can declare the copy constructor private (and in C++ 0x you'll be able to say =delete). This is unchanged with your proposal however, the problem is simply reversed, ie. you could foresee a question like: "Why doesn't the compiler generate a default copy constructor when it knows what to do?"

This will also be addressed in C++ 0x, as I believe there is an =default flag which will allow you to specify it:

class C {
public:
  C (C const &) = default;
};

It's beneficial to allow the compiler to implement the best possible version of the copy constructor.

Ease of use aside, today the compiler is able to choose the most efficient technique for copying the object. For example, it might just use memcpy with the object if it knows that that is safe to do so.

With your proposal, to achieve a similar optimzation today the compiler would need to analyze the constructor body to verify that it does nothing but shallow copy all the members. Not only is this non trivial, it can generally only happen when the constructor body is visible to all translation units.

In C++ 0x =default gets round this.

I wouldn't be surprised if, for C++ 0x, compilers and static analysis tools start generating warnings about "old style implicit default members".

Richard Corden
The new C++0x `default` and `delete` for compiler-generated constructors and special functions will be welcome. However, note that for the copy-ctor case my understanding is that the compiler will still generate one by default in all the same cases as it does today - the `delete` keyword is a useful, simple way to prevent that (in other words, there will be little need for `default` to be used for the copy-ctor). Pesky backwards compatibility.
Michael Burr
@Michael Burr: Yes, you're right. The existing behaviour of compilers regarding implicit default members will remain unchanged. As I said in the answer, the only glimmer of hope you have is that '=delete' and '=default' are manna from heaven for coding standards (and of course static analysis tools). Their presence allows tools to highlight classes that the developer did not explicitly intend to copy (ie. using defaulted copy constructor).
Richard Corden
@Richard: that would indeed be a nice added diagnostic tool.
Michael Burr
+5  A: 

From The C++ Programming Language, Section 11.3.4 Copying

...for types where the default copy constructor has the right semantics, I prefer to rely on that default. It is less verbose than anything I can write, and people should understand the default. Also, compilers know about the default and its possible optimization opportunities. Furthermore, writing out the memberwise copy by hand is tedious and error-prone for classes with many data members.

Basically, I read that as the default copy constructor saves you the effort, saves you from making errors caused by tedium, and helps optimize your code by removing the the temptation to optimize it by hand (by letting the compiler do it).

Bill the Lizard
That saying is quite a stretch from what he says in "Design and Evolution of C++", hmm.
Johannes Schaub - litb
@litb: The two passages do seem to be somewhat at odds. Maybe Stroustup originally included them reluctantly, then embraced them later?
Bill the Lizard
Michael Burr
They don't contradict up-front i think, but these two sentences are quite at odd, i think: "I personally consider it unfortunate that copy operations are defined by default" - "Also, compilers know about the default and its possible optimization opportunities. Furthermore, writing out the memberwise copy by hand is tedious and error-prone for classes with many data members.". @Michael, in the end i think you are right and in CPL, his sayings are based on status quo, while in the design book he shows us what he really thinks about that status.
Johannes Schaub - litb
@Michael Burr: I think the difference in wording between "I personally consider it **unfortunate** that copy operations are defined by default..." and "...I **prefer** to rely on that default." (emphasis mine) is what's confusing. I agree that the qualification of "...where the default copy constructor has the right semantics..." pretty much nullifies the perceived conflict.
Bill the Lizard
The idiom to disable is short, sweet and well understood. One glance and a reader knows what's intended. If defaults _weren't_ part of C++, hand-coding the current default behavior _isn't_ short and sweet. Readers would need to verify that every field is indeed copied or whatever. IMHO this decision went the more prudent way.
Dilum Ranatunga
A: 

Because C++ is not garbage collected, it forces you to keep track of all pointer owners, which is in practice impossible to do, unless you simplify the problem by using lots of copying all over the place so at least you know who owns the copy, and incidentally makes your program slower than a garbage collected one. Auto-generated copy constructors are a nail in the coffin that was put there to hide the gaping hole to hell that is new and delete.

peufeu