Modern ATL/MFC applications now have access to a new shared pointer class called CAutoPtr, and associated containers (CAutoPtrArray, CAutoPtrList, etc.).
Does the CAutoPtr class implement reference counting?
Having checked the CAutoPtr source, no, reference counting is not supported. Using boost::shared_ptr instead if this ability is required.
The documentation for http://msdn.microsoft.com/en-us/library/txda4x5t(VS.80).aspx
From reading this it looks like it tries to provides the same functionality as std::auto_ptr i.e. It uses ownership semantics. Only one CAutoPtr object holds the pointer and assignment transfers ownership from one CAutoPtr object to another.
Related
Hi I'm wondering if there is any C++ standard that allows the compiler to "share" the data with an object.
IE
LinkedList a = std::share(myLinkedListObject);
In which case the data of a is identical to myLinkedListObject and they share the same reference to memory. In such instance the ownership of the data could either be handled by a shared_ptr or the original object (myLinkedListObj) would retain ownership and control the lifespan of the data.
I acknowledge that the intuitive response and solution would simply use a pointer to the appropriate object but I am creating a wrapper class for a set of data in which case the fields of the wrapper class be the different but the data itself be identical.
There is nothing built in to C++ that codifies the semantics you want, mostly because unlike move and copy - the full behavior of the source and destination objects aren't really well defined. For example, what if you modify the source object a after your "share" operation? Should the the source list also reflect your modification?
If so, then you want some type of reference. Depending on the surrounding code and the ownership of the source object, you might be able to accomplish that with a plain reference or pointer, or you may need to use some type of smart pointer like a shared_ptr.
If not, then you are really talking about a copy operation: the source is copied to the destination, but they have distinct states after that point. In this case sharing the underlying state is still possible, but any write operation to either object needs to modify only the written object. This is referred to as copy-on-write (COW) and can be used to implement certain operations in an efficient way without affecting copy semantics.
You could implement copy-on-write semantics yourself depending on your use case. For example, if you have a linked list of immutable objects, a share operation could conceivably simply point at the original list, and any mutations would adjust only the necessary nodes to ensure that only the written list is logically modified.
In your specific case, it isn't really clear which of these options you want (if either). You mention that you want to create a wrapper object around some data in which the fields of the wrapper object may be different but the underlying data will be the same. That itself doesn't require any tricks at all: you just have a wrapper object which has fields, and then the data field which is shared must be a pointer or reference1 to a data object with appropriate lifetime semantics (e.g., shared_ptr).
1 In general, reference members are not too useful and pointers (dumb or smart) should generally be preferred.
std::unique_ptr uniquely controls the object it points to and, hence, does not utilize reference counting. A singleton ensures only one object may be created utilizing reference counting.
Would then std::unique_ptr perform identically to a singleton?
A singleton ensures only one instance of a type.
A unique_ptr ensures only one smart pointer to any instance.
Would then std::unique_ptr perform identically to a singleton?
No. Let's say we have class Foo that's intended to be a singleton. Using a typical singleton pattern, there's no way to construct more than one Foo.
Having a std::unique_ptr<Foo> means there will be one pointer to a particular instance of Foo, but that doesn't prevent the creation of other instances of Foo (either with other unique_ptrs or with raw pointers to local variables). Thus Foo, wouldn't be a singleton.
std::unique_ptr achieves single ownership semantics by only providing a move constructor and no copy constructor or assignment operator.
It is not a case of singleton at all, since you can have multiple unique_ptrs referencing different instances of the same type. A singleton doesn't let you construct the type directly, but provides an accessor that manages a sole instance.
Also, Drew's assertion that
"A unique_ptr ensures only one smart pointer to any instance."
is false. If you simply do:
T* nt = new T;
std::unique_ptr<T> up1(nt);
std::unique_ptr<T> up2(nt);
then you have two unique pointers owning the same resource - and you will only notice a problem at run time, not compile time. Of course, this is incorrect usage of unique_ptr, but this reinforces that a unique_ptr does not ensure you anything, it is simply a pointer container that holds sole ownership from its own perspective, and through its api, makes it hard to accidentally create temporary copies.
Furthermore, you can have other (smart) pointer types pointing to the same raw pointer/resource independently of any unique_ptr. It is completely up to the using code to define ownership and lifetime policies of its resources and smart pointer instances
Correct me if I'm wrong, but as far as I remember a singelton is a class which can only have one instance. That's completely different. So no.
I have a situation where some object has to be passed as an argument of a thread callback function. Object is created dynamically and after it is passed to the thread, object is not needed/used in that context (in a method which starts a thread) any more. Thread function is now the only context which should own the object.
Assuming I want to use some Boost smart pointer (instead of passing to the thread a raw pointer), which one would be the most appropriate here? What is the best practice in this case?
What I actually need is std::auto_ptr with its move semantics through copy constructor. I believe that this smart pointer would perfectly fit here but it is deprecated for well-known reasons (and I cannot rely on tr1 and C++11 pointers; must (and want to) use Boost only as this code is shared between projects that must compile both in Visual Studio 2008 and 2010).
boost::shared_ptr is an option - I could pass it by value but think it would be overkilling. Is there any chance of emulating move semantics (in a safe way) with boost::scoped_ptr? I don't need reference counting here as am not sharing object between two contexts, I just want to transfer the ownership over object from one context to another.
You could use boost::interprocess::unique_ptr, or write your own unique_ptr using Boost.Move.
boost::interprocess::unique_ptr uses Boost.Move in its implementation, and Boost.Move emulates C++11 move semantics C++03.
shared_ptr works well for most situations (including yours). You can use this pattern:
shared_ptr<MyT> param = .....;
thread = boost::thread(thread_routine, param);
param.reset();
... and now only thread_routine holds the object.
make_shared is more performant than separately calling new and creating a shared_ptr because make_shared allocates space for the reference count and weak count in the same memory block as the client object instance (effectively giving the shared_ptr most of the performance benefits of an intrusive_ptr).
enable_shared_from_this gives a shared pointer without having a reference to any shared pointer. Therefore things like the reference and weak count have to be somehow accessible from inside the client object. Therefore, it would be sensible for enable_shared_from_this to cause an intrusive count similar to make_shared.
However, I have no idea how something like that might be implemented (and I'm not sure I'd follow what was going on in there even if I look at the actual source).
Would it make sense then (for performance reasons) to tag my class with enable_shared_from_this if I know it's only ever going to be used as a shared_ptr and never as a raw object?
I have never dug into the details of implementation, but for shared_from_this to work, the object must already be managed by an external shared_ptr, so it is to some extent unrelated. I.e. the first shared_ptr might have been created with make_shared in which case the count and object are together (as you say intrusive pointer like), but that does not need to be the case.
My first guess is that enable_shared_from_this adds the equivalent of a weak_ptr, rather than a shared_ptr. EDIT: I have just verified the implementation in gcc4.6:
template <typename _Tp>
class enable_shared_from_this {
...
mutable weak_ptr<_Tp> _M_weak_this;
};
I don't believe so. How enable_shared_from_this is implemented isn't strictly defined, but an example implementation is present in the standard that corresponds to how boost does it. Basicaly, there is a hidden weak_ptr that shared_ptr and friends has access to... anytime a shared_ptr is given ownership of an object derived from enable_shared_from_this, it updates that internal pointer. Then shared_from_this() simply returns a strong version of that weak pointer.
In the general case, the implementation can't really assume that nobody will ever go shared_ptr(new T) instead of using make_shared, so an intrusive reference count would be risky. You can instead make that guarentee yourself, by whatever means you use to construct the objects in the first place.
Boost's enable_shared_from_this does not change the implementation of shared_ptr itself. Remember that shared_ptr is paired with weak_ptr - this means that, even after the object is deleted, the tracking data may need to remain around to tell the weak_ptr that the object is dead. As such, it can't be embedded into the object, even with enable_shared_from_this. All enable_shared_from_this does is embed a pointer to said tracking data into the object, so a shared_ptr can be constructed with just a pointer to the object.
This is also why intrusive_ptr cannot have a weak_intrusive_ptr variant.
This is a simplified example to illustrate the question:
class A {};
class B
{
B(A& a) : a(a) {}
A& a;
};
class C
{
C() : b(a) {}
A a;
B b;
};
So B is responsible for updating a part of C. I ran the code through lint and it whinged about the reference member: lint#1725.
This talks about taking care over default copy and assignments which is fair enough, but default copy and assignment is also bad with pointers, so there's little advantage there.
I always try to use references where I can since naked pointers introduce uncertaintly about who is responsible for deleting that pointer. I prefer to embed objects by value but if I need a pointer, I use auto_ptr in the member data of the class that owns the pointer, and pass the object around as a reference.
I would generally only use a pointer in member data when the pointer could be null or could change. Are there any other reasons to prefer pointers over references for data members?
Is it true to say that an object containing a reference should not be assignable, since a reference should not be changed once initialised?
My own rule of thumb :
Use a reference member when you want the life of your object to be dependent on the life of other objects : it's an explicit way to say that you don't allow the object to be alive without a valid instance of another class - because of no assignment and the obligation to get the references initialization via the constructor. It's a good way to design your class without assuming anything about it's instance being member or not of another class. You only assume that their lives are directly linked to other instances. It allows you to change later how you use your class instance (with new, as a local instance, as a class member, generated by a memory pool in a manager, etc.)
Use pointer in other cases : When you want the member to be changed later, use a pointer or a const pointer to be sure to only read the pointed instance. If that type is supposed to be copyable, you cannot use references anyway. Sometimes you also need to initialize the member after a special function call ( init() for example) and then you simply have no choice but to use a pointer. BUT : use asserts in all your member function to quickly detect wrong pointer state!
In cases where you want the object lifetime to be dependent on an external object's lifetime, and you also need that type to be copyable, then use pointer members but reference argument in constructor That way you are indicating on construction that the lifetime of this object depends on the argument's lifetime BUT the implementation use pointers to still be copyable. As long as these members are only changed by copy, and your type don't have a default constructor, the type should fullfil both goals.
Avoid reference members, because they restrict what the implementation of a class can do (including, as you mention, preventing the implementation of an assignment operator) and provide no benefits to what the class can provide.
Example problems:
you are forced to initialise the reference in each constructor's initialiser list: there's no way to factor out this initialisation into another function (until C++0x, anyway edit: C++ now has delegating constructors)
the reference cannot be rebound or be null. This can be an advantage, but if the code ever needs changing to allow rebinding or for the member to be null, all uses of the member need to change
unlike pointer members, references can't easily be replaced by smart pointers or iterators as refactoring might require
Whenever a reference is used it looks like value type (. operator etc), but behaves like a pointer (can dangle) - so e.g. Google Style Guide discourages it
Objects rarely should allow assign and other stuff like comparison. If you consider some business model with objects like 'Department', 'Employee', 'Director', it is hard to imagine a case when one employee will be assigned to other.
So for business objects it is very good to describe one-to-one and one-to-many relationships as references and not pointers.
And probably it is OK to describe one-or-zero relationship as a pointer.
So no 'we can't assign' then factor.
A lot of programmers just get used with pointers and that's why they will find any argument to avoid use of reference.
Having a pointer as a member will force you or member of your team to check the pointer again and again before use, with "just in case" comment. If a pointer can be zero then pointer probably is used as kind of flag, which is bad, as every object have to play its own role.
Use references when you can, and pointers when you have to.
In a few important cases, assignability is simply not needed. These are often lightweight algorithm wrappers that facilitate calculation without leaving the scope. Such objects are prime candidates for reference members since you can be sure that they always hold a valid reference and never need to be copied.
In such cases, make sure to make the assignment operator (and often also the copy constructor) non-usable (by inheriting from boost::noncopyable or declaring them private).
However, as user pts already commented, the same is not true for most other objects. Here, using reference members can be a huge problem and should generally be avoided.
As everyone seems to be handing out general rules, I'll offer two:
Never, ever use use references as class members. I have never done so in my own code (except to prove to myself that I was right in this rule) and cannot imagine a case where I would do so. The semantics are too confusing, and it's really not what references were designed for.
Always, always, use references when passing parameters to functions, except for the basic types, or when the algorithm requires a copy.
These rules are simple, and have stood me in good stead. I leave making rules on using smart pointers (but please, not auto_ptr) as class members to others.
Yes to: Is it true to say that an object containing a reference should not be assignable, since a reference should not be changed once initialised?
My rules of thumb for data members:
never use a reference, because it prevents assignment
if your class is responsible for deleting, use boost's scoped_ptr (which is safer than an auto_ptr)
otherwise, use a pointer or const pointer
I would generally only use a pointer in member data when the pointer could be null or could change. Are there any other reasons to prefer pointers over references for data members?
Yes. Readability of your code. A pointer makes it more obvious that the member is a reference (ironically :)), and not a contained object, because when you use it you have to de-reference it. I know some people think that is old fashioned, but I still think that it simply prevent confusion and mistakes.
I advise against reference data members becasue you never know who is going to derive from your class and what they might want to do. They might not want to make use of the referenced object, but being a reference you have forced them to provide a valid object.
I've done this to myself enough to stop using reference data members.