Smart pointers as class members, to make copying more efficient

I'm just breaking into the use of Boost smart pointers for the purpose of making the copying of objects more efficient. Is this possible?
Usually when one makes a copy constructor and assignment operator, they look something like this:

But say you have "shared" smart pointers for your class members? Is it possible to just pass those around, thereby bypassing those expensive copy procedures? How would I set up my class that way? Yes, I am aware that if any instance of aclass writes to what the smart pointers contained, then all instances will change. The classes I want to write will treat these contained instances as read-only after they are created.

The reason I want to do this is I'd like to hide the use of smart pointers from the owners of aclass, thereby making it abstract. That why I'd have members like:

But say you have "shared" smart pointers for your class members? Is it possible to just pass those around, thereby bypassing those expensive copy procedures?

Yes, it is.

Originally Posted by Angus

How would I set up my class that way?

By storing the smart pointers as members.

Originally Posted by Angus

The reason I want to do this is I'd like to hide the use of smart pointers from the owners of aclass, thereby making it abstract.

As in you intend to abstract away the use of smart pointers from the users of your class? Logically, if you did your class design correctly, you can just do this without breaking client code since it is a change to implementation detail. The problem is that your class copying semantics will change, as you have anticipated, and this is a change to the class interface.

Originally Posted by Bjarne Stroustrup (2000-10-14)

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

Can you give me an example in a class declaration? And to be safe, an example of a copy constructor definition would be helpful, too.

My problem is that a typical copy constructor looks like this:

Code:

class aclass {
aclass(const aclass &other);

Now if there's a "shared" smart pointer that's a member of aclass, call it m_srtptr, and the copy constructor tries to copy m_srtptr from other it will want to increment the reference counter, but other is const. See what I'm getting at?

Now if there's a "shared" smart pointer that's a member of aclass, call it m_srtptr, and the copy constructor tries to copy m_srtptr from other it will want to increment the reference counter, but other is const. See what I'm getting at?

This is not a problem, you can copy a const smart pointer without any issues. If the reference of the const smart pointer needs to be incremented during a copy (like with shared_ptrs), then that reference count will be declared as mutable.

And to be safe, an example of a copy constructor definition would be helpful, too.

A pretty helpful copy constructor definition would be to show you nothing, since the compiler generated copy constructor would suffice

Originally Posted by Angus

Now if there's a "shared" smart pointer that's a member of aclass, call it m_srtptr, and the copy constructor tries to copy m_srtptr from other it will want to increment the reference counter, but other is const. See what I'm getting at?

Firstly, it is not the shared_ptr that you want to be const, but what it points to. Then, even if the shared_ptr was const, you need not worry about the reference counter during copying (other than the need to avoid a cycle).

Originally Posted by Bjarne Stroustrup (2000-10-14)

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

Firstly, it is not the shared_ptr that you want to be const, but what it points to. Then, even if the shared_ptr was const, you need not worry about the reference counter during copying (other than the need to avoid a cycle).

He is talking about the shared pointer being a member variable. If the class is const, then so are it's member variables. This still doesn't matter though, because you can copy a const shared_ptr.

Ah yes, I see that I did not mentally register the context that this would be a const reference.

Originally Posted by bithub

This still doesn't matter though, because you can copy a const shared_ptr.

Yes, that is part of what I mean by "even if the shared_ptr was const, you need not worry about the reference counter during copying". The other part is that the reference counter itself is implementation detail, even though its existence (or at least the concept thereof) is exposed in the interface of shared_ptr. Consequently, this is a special case where the observable state of the object might correctly change even if it is constant.

Originally Posted by Bjarne Stroustrup (2000-10-14)

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

Ah yes, I see that I did not mentally register the context that this would be a const reference.

Yes, that is part of what I mean by "even if the shared_ptr was const, you need not worry about the reference counter during copying". The other part is that the reference counter itself is implementation detail, even though its existence (or at least the concept thereof) is exposed in the interface of shared_ptr. Consequently, this is a special case where the observable state of the object might correctly change even if it is constant.

In fact, the most obvious implementation of shared_ptr involves keeping the refcount in a separate chunk of memory, which means that it's not actually within the shared_ptr itself, and can be modified even if the shared_ptr is const, and this does NOT require the use of "mutable"