tags:

views:

475

answers:

11

In writing a copy constructor for one of my classes ( which holds a few objects of other UDTs ), I am required to create a default constructor for those UDTs, even though they were never really meant to have one.

Is it fine to just implement a blank default constructor and be done with it? The only time the default constructor is invoked is during this copying, when the object is created and then the values of the corresponding object are copied to it. Thus, whatever values are assigned to the object in the default constructor will never actually be used.

The problem I see is that some member variables aren't initialized in a blank default constructor. Should I just write one that gives dummy values instead? Any other recommended ways to handle this?

Edit: I understand that a copy constructor doesn't NEED a default constructor if I were to define copy constructors for the other classes, but I didn't, so it does need it.

+2  A: 

You say:

when the object is created and then the values of the corresponding object are copied to it.

But ask yourself - how do the values of that "corresponding object" get there in the first place. I.e. how was the corresponding object created?

This previous SO discussion may help clarify matters for you.

Eli Bendersky
+4  A: 

Are you actually sure you need a copy constructor? It's unusual (but not impossible) to have a class where the default constructor would be OK, but you need a custom copy constructor. Perhaps you could post the code for your class?

anon
Yes because I need to do a deep copy.
Anonymous
C++ does not really use the term "deep copy" - things would be much clearer if you posted some code.
anon
Well what is it called if it isn't called deep copy?
Anonymous
+1  A: 

This doesn't sound like the best way to implement a copy constructor. If the contained types provide copy constructors themselves - use those. There might be a reason a type does not provide a default constructor after all.

Nikolai N Fetissov
+1  A: 
Victor Nicollet
A: 

You can prevent the default constructor by requiring the other object to have copy constructors also (Or use special constructor which pass in all information needed to construct the objects. Generally having default constructor which don't initialize all member variables is a very bad idea. At a minimum make sure the default constructors of the other class initializes all members.

Jim Kramer
+3  A: 

It sounds to me like you need to define copy c'tors for the other classes, as you are creating objects of them by copying other objects.

Amir Rachum
+4  A: 

If you use an initializer list in the copy constructor, you don't need a default constructor:

#include <iostream>
using namespace std;
class Foo {
  Foo();            /* no default constructor */
public:
  Foo(int i)        { cout << "Foo constructor (int)"  << endl; }
  Foo(const Foo& f) { cout << "Foo constructor (copy)" << endl; }
};
class Bar {
  Foo f;
public:
  Bar()             : f(1)   { cout << "Bar constructor (default)" << endl; }
  Bar(const Bar& b) : f(b.f) { cout << "Bar constructor (copy)"    << endl; }
};
int main(void) {
  Bar b;
  Bar b_=b;
  return 0;
}

Results in:

Foo constructor (int)
Bar constructor (default)
Foo constructor (copy)
Bar constructor (copy)
mrkj
Both those classes have constructors other than the copy constructor. And what you say is not true.
anon
That's a pretty weird statement. In the current C++ you can't "call" one constructor from another. So, if you use the copy-constructor, you simply *can't* use the default constructor (it is simply impossible), regardless of whether you are using the initializer list or not.
AndreyT
The point in the original example was that Foo's default constructor wasn't called by copying. I've edited the example to remove Foo's default constructor to better illustrate that point. The classes obviously have constructors other than the copy constructor -- how else are you going to create the first instance of the object? My understanding is that the objective is to avoid adding an unwanted default constructor.
mrkj
The point is, that if you only have a copy constructor, you can only create objects by copying - you need at least one other constructor. But if you explicitly declare a copy ctor, the default does not get synthesised, so you have to explicitly declare that too.
anon
This answer got me thinking in the right direction, and you understood the meaning of the question. I hadn't thought about using an initializer list. That being said, if I wanted to implement a copy assignment, would it be possible to somehow use the same strategy?
Anonymous
P.S. I don't want to implement copy assignment, just curious.
Anonymous
mrkj
Thanks. This was very helpful.
Anonymous
A: 

Remember a thumb rule that as far as something is not part of specification , compiler won't do it for you.

If your class contain user defined type and when you create object of it , then compiler has to call default constuctor for each object.

But to initialize data members of object is not complier's task, but you are suppose to do it.

For the case you have mentioned , you need your own custom copy constructor and assignment operator.

Ashish
A: 

If you don't want the compiler to generate a copy constructor or don't want a copy constructor at all, then declare a private copy constructor but don't provide any definition (code) for it. The compiler will see the declarations and not generate one. Also do this with the assignment operator.

I do this with my singleton classes.

Thomas Matthews
A: 

If your class isnt meant to be defaultly constructed, don't create a default constructor. If it is, then I'm sure you can figure out a sensible initialization, so that's what you should be using.

rmn
A: 

The question, the way you stated it, appears to make no sense. Copy-constructor does not need the default constructor, as you seem to believe. Copy-constructor is a completely independent full-fledged constructor that construct an object completely by itself.

If you construct your objects with copy-constructor, then you don't need a default one. If you construct your objects with default constructor, then you can't use the copy-constructor on them. It is not possible to "apply" two different constructors to the same object.

If you construct your objects in both ways, then they become two completely independent constructors, each having its own independent purpose. In this case the question you should be asking yourself is how you want your objects to be defualt-constructed. Only you know that.

Again, you need to clarify your question. I would suspect (from your description) that maybe what you are trying to implement is not copy-constructor, but a copy-assignment operator. But that's just a wild guess.

AndreyT
No. Read the edit.
Anonymous