13

From cplusplus.com:

Rarely you will come across a class that does not contain raw pointers yet the default copy constructor is not sufficient. An example of this is when you have a reference-counted object. boost::shared_ptr<> is example.

Can someone elaborate on this? If we have a class containing a boost::shared_ptr, won't that get copy constructed when the class gets copy constructed - and hence won't the shared_ptr constructor do the right thing and increase the reference count? The following code, for example, copies Inner properly - why wouldn't this work for shared_ptr?:

#include <iostream>
using namespace std;

class Inner
{
public:
 Inner() { cout << "inner default constructed" << endl;}
 Inner(const Inner& other) { cout << "inner properly copied" << endl;}
};

class Outer
{
 Inner i;
};

int main() { Outer o; Outer p(o); return 0;}
Sideshow Bob
  • 4,566
  • 5
  • 42
  • 79
  • 13
    Maybe you didn't get not tripped up by the missing double negatives that aren't in that statement? – Kerrek SB Jul 24 '13 at 12:06
  • Forget it, it is just bollocks. Pretend it didn't mention shared_ptr. I guess this is yet another of the reasons cplusplus.com is so reviled. – R. Martinho Fernandes Jul 24 '13 at 12:09
  • So to ask a better question then. When people say "the default copy constructor does a shallow copy", does that mean "it calls the copy constructors of all the members in turn" or "it just does memcpy() on the class instance" – Sideshow Bob Jul 24 '13 at 12:11
  • 2
    This shallow copy business is just confusing. It just does an member-wise copy. What actually happens during the copy depends on the types of the data members involved. – juanchopanza Jul 24 '13 at 12:20

3 Answers3

20

The default copy constructor will use the copy constructor for each member variable, or bit-wise copy for built-in types.

If you are using a shared pointer of some kind, the copy constructor will increment the shared count and both the original and the new objects will point to the same object.

In some cases, this is what you want; copying the pointer and correctly managing the reference count so that the resource can be freed when it is no longer used.

The context of the cited article is in copying an entire object. In this case, each object would be expected to have its own copy of its subobjects, and not share subobjects with other instances. In this case, shared_ptr is probably the wrong choice, and will definitely not deep-copy the subobjects.

The paragraph is badly phrased, but I'm sure it is talking about deep-copy but saying that shared_ptr will not provide that deep-copy. Which is true, because that isn't what it is designed for.

cdmh
  • 3,294
  • 2
  • 26
  • 41
9

Can someone elaborate on this?

Not really; it's gibberish.

If we have a class containing a boost::shared_ptr, won't that get copy constructed when the class gets copy constructed - and hence won't the shared_ptr constructor do the right thing and increase the reference count?

That's right. shared_ptr is properly designed with valid copy semantics, so there's no need to deal with it specially when copying a class object containing one.

Possibly, the author meant that if you want to copy, rather than share, the shared object, then you'll need a copy constructor to make a new one. However, it's rather strange to be using a shared_ptr if you don't want shared ownership.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2

I think it means the new class will refer to the old class's resource, where you might expect a copy to be made of the old resource for the new class, as would happen if it were a full member of the class. Either is acceptable - it depends on what you are doing.

For example, if you copy a dog, and a dog has a bone, does the new dog get its own bone, or does it share the original bone?

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • That's what the previous paragraph in the linked article describes; if the object contains a raw pointer to a resource it manages (which is usually a very bad idea) then you'll need a copy constructor to deal with that. The quoted paragraph is simply gibberish. – Mike Seymour Jul 24 '13 at 12:57
  • If you want the copied object to have a copy of the original resource and not share it, you will need a copy constructor when using shared_ptr – Neil Kirk Jul 24 '13 at 12:59
  • I see. Yes, perhaps the author is trying to say that you'll need a copy constructor if you use a shared-pointer when you don't want its shared semantics. That's rather a strange thing to do though. – Mike Seymour Jul 24 '13 at 13:08