3

I am new to object oriented programming, and this may be a silly question, but I don't understand why is using class A code better to use than class B if you want to create copy of one object.

class A {
    int num;
public:
    A(const A &ref) : num(ref.num) {};
};

class B { 
    int num;
public:
    B(B *ptToClass) : num(ptToClass->num) {};
};

If I got this right, copy constructor is used in class A.

kkralj
  • 125
  • 2
  • 7
  • http://stackoverflow.com/a/18611518/1012759 it is forbidden by standard to accept pointers. – CyberGuy Sep 03 '15 at 17:29
  • 3
    @CyberGuy This question says "to copy the object", not "create a copy constructor". You can "copy the object" without a copy constructor. – Yakk - Adam Nevraumont Sep 03 '15 at 17:32
  • 1
    Are you sure class A is better? The two classes look pretty similar to me, one with a pointless copy constructor, and the other with a cryptic constructor which takes a pointer. – anatolyg Sep 03 '15 at 17:44
  • @anatolyg: Yes. Compilers optimize real copy constructors. There's even special wording to allow aggressive optimization; they might be removed altogether at times even when that eliminates side effects. – MSalters Sep 03 '15 at 23:47

5 Answers5

5

If you don't declare a copy constructor for your class, the compiler will declare one for you anyway. Classes have to have copy constructors. They're baked into the language and have special status. The language doesn't work without them.

Possibly the best example is that copy constructors are needed when passing by value. The compiler is going to implicitly call the copy constructor when you pass by value. It's not going to call the constructor B::B(B*).

So if you want your class to be copyable, you should define the copying logic in the copy constructor. It's just easier.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • "Classes **have to** have copy constructors." Not really. I don't really remember on what situation a compiler will not emit the copy constructors for you, but since C++11, you can delete the copy constructor explicitly. `std::unique_ptr` has no copy constructor. – lvella Sep 03 '15 at 18:27
  • 1
    @Ivella It still **has** a copy constructor, and this is important. If you try to copy a `std::unique_ptr`, it will select the copy constructor for the copy, and then you will receive an error since it is deleted. – Brian Bi Sep 03 '15 at 18:29
  • @Ivella Then, you are free to imagine that instead of me saying "a class always has a copy constructor", I am instead saying, "a declaration of a copy constructor is always available". This should not be controversial. – Brian Bi Sep 03 '15 at 18:33
4

Class A is flexible and safe: you create a copy from any A object you have, even if it's a temporary one.

Class B is less safe as you could invoke the constructor with a nullptr. It's less flexible because you can only use ypur constructor to copy an object from which you can get the address and which is not const.

B b1(...);        
const B b2(...); 
B fb();        // function returning a B

B b3(&b1);      
B b4(&b2);     // error b2 is const
B b5(&fb());   // error you can't take adress of a temporary 
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • The first point about B is true, the second is not (because `B` has an implicitly-defined copy constructor as well as the constructor taking a pointer, so it can still be copied) – Jonathan Wakely Sep 03 '15 at 18:50
  • @JonathanWakely Of course ! Sorry for my poor wording: I meant the constructor that was provided for B, and not the real copy constructor. I've edited. – Christophe Sep 03 '15 at 19:43
2

The thing is that if a constructor is considered to be a copy constructor by the compiler, it is used in special ways. For instance, if you have a function that takes a parameter of your type A by copy, like this:

void function(A obj) {
   // Do something with A
   // ...
}

And then you call that function:

int main() {
   A a_obj;
   function(a_obj);
}

the object obj received by function will be created by the copy constructor you provided. So, it is a nice thing to provide copy constructor for your classes that are meant to be copied, so that them fits more nicely with the languages features and libraries.

There is no problem in creating a constructor of the kind in your class B, if that fit your needs in your application, but that will not be understood by the compiler as a copy constructor, and won't be used when the compiler or libraries needs to copy your objects.

lvella
  • 12,754
  • 11
  • 54
  • 106
0

It is forbidden by standard to use pointers in copy constructors:

C++ draft standard n3376 - section 12.8.2:

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments

Why is the argument of the copy constructor a reference rather than a pointer?

Community
  • 1
  • 1
CyberGuy
  • 2,783
  • 1
  • 21
  • 31
0

I think a more appropriate question to ask is: when to provide a user-defined copy constructor over the default one provided by the compiler?

As we know, the compiler provides a copy constructor (the default one) which does a memberwise copy.

This memberwise copy is not bad as long as the class is a simple concrete type (that behaves for the most part like a built-in type). But for complex concrete types or classes with hierarchies, memberwise copy is not a good idea, and the programmer is highly advised to provide his own implementation of the copy constructor (that is, provide user-defined copy constructor).

As a thumb rule, it is a good idea to provide user-defined copy constructor in the class.

Asif
  • 664
  • 1
  • 7
  • 14