I'm coming from Java and attempting to learn C++.
As far as I can tell, using Pointers is very similar to how reference variables work in Java, in that you pass a memory address to the value. So I feel like I have gotten a pretty good understanding of them. I also understand that these variables are stored on the heap.
However, I see that there is another way in which you can declare variables in C++, without the new operator/pointers simply doing something like:
Employee boss("Frank");
Which will create a value of Employee with "Frank" as the parameter. These variables are stored on the stack.
So, you have these 2 very different ways of creating variables and both with their own unique behavior (with memory management as well?).
My question is, when is it appropriate to use pointers VS values? What is the best practice? How should I know in what way I want to declare my variables most of the time?
C++ pointers operate exactly like Java objects, in that they may be invalid (NULL) and are cheap to pass to procedures.
C++ references are a thin wrapper around pointers. They're not supposed to be invalid, but in some cases may be. For example, a reference might be created from a NULL pointer, or the memory it references might be deleted.
In the code example you give:
Employee boss("Frank");
you are using something called a "value". Unlike pointers and references, values are the object they represent, not an indirection.
My question is, when is it appropriate
to use Pointers VS [values]?
What is the best practice? How should
I know in what way I want to declare
my variables most of the time?
C++ doesn't have garbage collection, so values are used when the scope of a variable is limited. For example, instead of allocating one with new and deallocating with delete for every variable in a procedure, you can allocate them on the stack and not worry about the memory.
There are two different issues at play here: Creating objects, and referring to them.
Creating
There are two places that objects are created: the stack and the heap. If you use the syntax you described:
Employee boss("Frank");
Will create it on the stack. If you write this:
Employee* boss = new Employee("Frank");
It will create it on the heap. If you're not familiar with the concepts of stack and heap, it is vitally important to being a good C++ coder, so learn about it!
Referring
Referring to objects is somewhat different. Regardless of how an object is created, it can be referred to using a pointer or a reference (or just a standard variable). Using references and pointers in C/C++ is actually very much the same thing, though there are important differences.
When using pointers or references, a copy of the object is not made.
// No copies made:
Employee& frank = boss; // Using References
Employee* frank = &boss; // Using a Pointer
A copy is made when you use neither.
// Copy is made:
Employee frank = boss;
So when would you use pointers, and when would you use references? I find that a good practise is to only use pointers when it is meaningful for it to be null. If something should not be null, make it a reference.
Generally you want to stick with references as much as possible. The reason is because of RAII. Basically, this guarantees no memory leaks if you are using RAII.
However, IMO you should use pointers when the objects you are using would be very expensive to copy. Passing around container types will cause duplicates of the containers to occur... not a great idea.
The best way is to use smart pointers... basically references which hold a pointer and keep track of the number of references to the pointer. This is really the best of both worlds... Cheap initialization/copies and reference counting to practically eliminate memory leaks.
Note: I will use "object" to refer to objects and to primitive types such as int, float... these are not the same in C++ (but usually you can ignore this).
Use values when you are creating an object that you control from that scope, and it should die when that scope ends. Also, use value when you want to use a copy of an external object, but you only want to handle the copy not the real object. Example:
int myFunction(int external_value1, Object external_value2){
---
}
Use pointers/references when you are creating an Object that should not die when it's scope of creation ends (ensure to pass a pointer to it to some other scope!), or when using an external value that is expensive to copy (like a container), or when you want to operate directly on that external object and not on a copy of it. That's why I/O parameters of functions are usually pointers or references, as you want to act on an external object (defined outside of the scope of the function) directly and not on a local copy. Example:
int myOtherFunction(int *external_value1, Object *external_value2{
---
}
In this example, if you operate on the value pointed by the parameters, you are affecting exactly that: the value those pointers point at, thus changing a variable outside of the function scope. In fact is a pass-by-value, but you are copying only the pointers, and using them to "attack" the external values.
References are, as stated by other post, just syntactic sugar for pointers. Once you understand pointers, you understand references ;).
The C++ FAQ has a good answer to this specific question:
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6
When to use pointers and when not to?
C++ References and Java References
Switching from Java to C++ - What's the Easy Way?
many more
Two different beasts: if you assign by pointer, you end-up with n-to-1 relationships which you must handle through proper resource management. This is normally taken care of in Java.
In what you call "Reference Objects", you get different objects (which need to be tracked etc.).
Related
I am learning C++. I have C, C#, ObjC background. Pretty higher level languages.
On C# or ObjC , it's trivial returning heap allocated object as a result of a function or method. Because the cleanup of objects are managed (by convention). It will be destroyed at proper time.
But I don't know how should I handle this in C++.
For example,
std::string* makeString()
{
std::string* str = GetSomeStringFromArbitrarySource ();
SaveSomewhereElseInternally (str);
return str;
}
void useString ()
{
std::string* str = makeString ();
// Where and how should I cleanup the `str` object?
// It is not safe `delete str` here because it may be used on another place.
}
What is the recommended and conventional way to cleanup heap allocated object when it is passed over many functions?
I looked several smart pointers, but they don't look really reduce complexity or things to care. Am I misunderstanding the smart pointers?
I looked several smart pointers, but they don't look really reduce complexity or things to care. Am I misunderstanding the smart pointers?
Most likely, yes. In C++, since you have to handle this yourself (no GC will clean it up for you), you need a way to track the usage of each and every object.
You can manually match every new with a delete, but this is sometimes difficult or impossible, such as in your scenario above. There is no way to know whether the object is being used elsewhere.
Smart pointers solve this by managing the lifetime for you, so you don't need to delete. They use various mechanisms to track how many places the object is being used, and call delete when the last one is done.
That being said, there isn't much reason in this specific case to use pointers at all. If you're working with std::string, you can pass the string around by value and it will never be an issue.
You are misunderstanding the smart pointers most probably by the same reason why you wrote:
std::string* makeString()
Instead of what most C++ programmers would write instead:
std::string makeString()
You would need to better understand object lifetime in C++ and then smart pointers concept would be much easier.
You need to figure out the desired lifetime for your objects, and then use the type system to enforce that lifetime.
From your example, it isn't at all clear when you want the object to be destroyed.
In C++, it is common for objects to be passed around by value (as primitive types are in Java/C#/etc), so unless you have some need to share the std::string between different pieces of code, the usual thing would be to just return the string by value (write makeString as std::string makeString()).
If you do need to have multiple places referencing the same object, you should think carefully about the design, and decide what single part of the program can safely control the lifetime of the object. Create the object by value in that place, and then pass pointers and references elsewhere.
Possibly you are misunderstanding smart pointers. In C++ the alternative is that the programmer needs to track the lifetime and usage of dynamically allocated objects. This affects the design of the software and also leads to human errors creeping in. When you use smart pointers , the lifetime of an object is pretty much taken care of for you.
I was brought up with the classical style of C++ (no smart pointers) and so I'm able to program that way , if required, but if you're starting out with c++ then smart pointers really is a must.
If you can use C++11 use shared pointers. These pointers implement a mechanism to delete the allocated object once the last of them is destroyed. If you are using C++03, use boost's shared pointers. If you can not use either, try to wrap heap allocations in classes you allocate on the stack, then pass references to those around, also give the RAII wiki a read.
I think I have a considerable experience with normal (functional) designed patters, as described e.g. in the gang of four book, which I mainly used in java and C#. In these "managed" languages this is pretty much everything you need to know to get your work done.
However, in C++ world the developer also has the control of how all the objects get allocated, passed around and deleted. I understand the principles (I read Stroutrup among other texts), but it still takes me a lot of effort to decide which mechanism is best for a given scenario - and this is where a portfolio of memory-related design patterns would be useful.
For example, yesterday I had to create a class Results, that was a container for a few objects and a collection (std::vector in this case) of yet another type of objects. So there are a few design questions I couldn't really answer:
Should I return this class by value, or by smart pointer?
Inside the class, should the vector and the objects be normal members, or should they be stored as smart pointers again?
In the vector, should I store the objects directly, or smart pointers to them again?
What should the getters defined on my Results class return (i.e. values, references or smart pointers)?
Of course, smart pointers are cool and what not, but they create syntactic clutter and I am not convinced if using malloc for every single object is optimal approach.
I would be grateful for answers for the specific points above, but even more for some longer and more general texts on memory-related design patterns - so that I can solve the problems I will have on Mondays as well!
The answer to all of your questions ends up being one and the same: it depends on whether you need reference semantics or value semantics (with some caveats to be taken into account).
If you need reference semantics, which is what you have by default in languages like Java and C# for UDTs (User-defined Data Types) declared with the class keyword, then you will have to go for smart pointers. In this scenario you want several clients to hold safe aliases to a specific object, where the word safe encapsulates these two requirements:
Avoid dangling references, so that you won't try to access an object that doesn't exist anymore;
Avoid objects which outlive all of the references to them, so that you won't leak memory.
This is what smart pointers do. If you need reference semantics (and if your algorithms are not such to make the overhead of reference counting significant where shared ownership is needed), then you should use smart pointers.
You do need reference semantics, for instance, when you want the same object to be part of several collections. When you update the object in one collection, you want the representations of the same object in all the other collections to be consistently updated. In this case, you store smart pointers to your objects in those collections. Smart pointers encapsulate the identity of an object rather than its value.
But if you do not need to create aliases, then value semantics is probably what you should rely on. This is what you get by default in C++ when you declare an object with automatic storage (i.e. on the stack).
One thing to consider is that STL collections store values, so if you have a vector<T>, then copies of T will be stored in your vector. Always supposing that you do not need reference semantics, this might become anyway an overhead if your objects are big and expensive to copy around.
To limit the likelyhood of this scenario, C++11 comes with move operations, which make it possible to efficiently transfer objects by value when the old copy of the object is no more needed.
I will now try to use the above concepts to answer your questions more directly.
1) Should I return this class by value, or by smart pointer?
It depends on whether you need reference semantics or not. What does the function do with that object? Is the object returned by that function supposed to be shared by many clients? If so, then by smart pointer. If not, is it possible to define an efficient move operation (this is almost always the case)? If so, then by value. If not, by smart pointer.
2) Inside the class, should the vector and the objects be normal members, or should they be stored as smart pointers again?
Most likely as normal members, since vectors are usually meant to be conceptually a part of your object, and their lifetime is therefore bound to the lifetime of the object that embeds them. You rarely want reference semantics in such a scenario, but if you do, then use smart pointers.
3) In the vector, should I store the objects directly, or smart pointers to them again?
Same answer as for point 1): do you need to share those objects? Are you supposed to store aliases to those objects? Do you want changes to those objects to be seen in different parts of your code which refer those objects? If so, then use shared pointers. If not, is it possible to efficiently copy and/or move those objects? If so (most of the time), store values. If not, store smart pointers.
4) What should the getters defined on my Results class return (i.e. values, references or smart pointers)?
Same answer as for point 2): it depends on what you plan to do with the returned objects: do you want them to be shared by many parts of your code? If so, return a smart pointer. If they shall be exclusively owned by just one part, return by value, unless moving/copying those objects is too expensive or not allowed at all (quite unlikely). In that case, return a smart pointer.
As a side note, please be aware that smart pointers in C++ are a bit trickier than Java/C# references: first of all, you have two main flavors of smart pointers depending on whether shared ownership (shared_ptr) or unique ownership (unique_ptr) is desired. Secondly, you need to avoid circular references of shared_ptr, which would create islands of objects that keep each other alive even though they are no more reachable by your running code. This is the reason why weak pointers (weak_ptr) exist.
These concept naturally lead to the concept of responsibility for managing the lifetime of an object or (more generally) the management of a used resource. You might want to read about the RAII idiom for instance (Resource Acquisition Is Initialization), and about exception handling in general (writing exception-safe code is one of the main reasons why these techniques exist).
How do pointers work with the concepts of Object oriented programming?
As I understand it (and please recognize, I'm classified as an ID-10T), the main tenet of OOP is containment and keeping management responsibility (memory/implementation/etc.) contained within the class; but when an object's method returns a pointers it seems like we are 'popping' the object. Now, somebody might need to worry about:
Are they supposed to delete the pointer's associated object?
But what if the class still needs the object?
Can they change the object? If so, how? (I recognize const might solve this issue)
and so forth...
It seems the user of the object now needs to know much more about how the class works and what the class expects of the user. It feels like a "cat's out of the bag" scenario which seems to slap in the face of OOP.
NOTE: I notice this is a language independent question; however, I was prompted to ask the question while working in a C++ environment.
What you describe are ownership issues. These are orthogonal (i.e. independent, you can have either without the other or even both) to object orientation. You have the same issues if you do not use OOP and juggle pointers to POD structs. You don't have the issue if you use OOP but solve it somehow. You can (try to) solve it using more OOP or in another way.
They are also orthogonal to the use of pointers (unless you nit pick and extend the definition of pointer). For example, the same issues arise if two separate places hold indices into an array and mutate, resize and ultimately delete the array.
In C++, the usual solution is to select the right smart pointer type (e.g. return a shared pointer when you wish to share the object, or a unique pointer to signify exclusive ownership), along with extensive documentation. Actually, the latter is a key ingredient in any language.
One OOP-related thing you can do to help this is encapsulation (of course, you can have encaptulation just fine without OOP). For instance, don't expose the object at all, only expose methods which query the object under the hood. Or don't expose raw pointers, only expose smart pointers.
For starters... You can't have polymorphism without pointers or
references. In C++, traditionally, objects are copied, and have (for
the most part) automatic storage duration. But copy doesn't work with
polymorphic objects—they tend to get sliced. And OO also often
means identity, which in turn means you don't want copy. So the
solution is for the object to be dynamically allocated, and to pass
around pointers. What you do with them is part of the design:
If the object is logically part of another object, then that object is
responsible for its lifetime, and objects which receive the pointer
should take steps to ensure that they don't use it after the owning
object disappears. (Note that this is true even in languages with
garbage collection. The object won't disappear as long as you've got a
pointer to it, but once the owning object is invalid, the owned object
may become invalid as well. The fact that the garbage collector won't
recycle the memory won't guarantee that the object you point to is
usable.)
If the object is a first class entity itself, rather than being
logically part of another object, then it should probably take care of
itself. Again, other objects which may hold a pointer to it must be
informed if it ceases to exist (or becomes invalid). The use of the
Observer pattern is the usual solution. Back when I started C++, there
was a fashion for "relationship management", with some sort of
management classes where you registered relationships, and which
supposedly ensured that everything worked out OK. In practice, they
either didn't work, or didn't do any more than the simple observer
pattern, and you don't hear any more of them today.
For the most part, your precise questions are part of the contract that
each class has to establish for each of its functions. For true OO
classes (entity objects), you should probably never delete them: that's
there business, not yours. But there are exceptions: if you're dealing
with transactions, for example, a deleted object cannot be rolled back,
so when an object decides to delete itself, it will usually register
this fact with the transaction manager, who will delete it as part of
the commit, once it's established that roll back won't be necessary. As
for changing the object, that's a question of the contract: in a lot of
applications, there are mapping objects, which are used to map an
external identifier of some sort to the object. With the goal, often,
of being able to modify the object.
From my understanding and experience, it generally revolves around what it is that you are trying to do as well as the language using pointers (e.g. C++ vs Objective-C).
Usually, though, in C++ terms, I've found that it's best to return either a reference to a smart pointer (such as std::shared_ptr) by reference (perhaps even const reference, depending on the situation), or simply hide the pointer in the class, and if it NEEDS to be accessed or used by something outside of it, use a getter method which either copies the pointer and returns that, or returns a reference to a pointer (granted, AFAIK ref-to-ptr is only possible in C++). If someone doesn't know that you shouldn't delete a ref-to-ptr in most situations (of course, if its deallocation is handled by the class internally), you should really think twice about whether or not they're ready to be doing C++ stuff on your team.
It's fairly common to just use public references for class members if they can be stack allocated (i.e., if they won't take up too much memory), while managing heap allocated objects internally. If you need to set the class member outside of the class, it's possible to just use a set method which takes the required value, rather than access it directly.
After reading some tutorials I came to the conclusion that one should always use pointers for objects. But I have also seen a few exceptions while reading some QT tutorials (http://zetcode.com/gui/qt4/painting/) where QPaint object is created on the stack. So now I am confused. When should I use pointers?
If you don't know when you should use pointers just don't use them.
It will become apparent when you need to use them, every situation is different. It is not easy to sum up concisely when they should be used. Do not get into the habit of 'always using pointers for objects', that is certainly bad advice.
Main reasons for using pointers:
control object lifetime;
can't use references (e.g. you want to store something non-copyable in vector);
you should pass pointer to some third party function;
maybe some optimization reasons, but I'm not sure.
It's not clear to me if your question is ptr-to-obj vs stack-based-obj or ptr-to-obj vs reference-to-obj. There are also uses that don't fall into either category.
Regarding vs stack, that seems to already be covered above. Several reasons, most obvious is lifetime of object.
Regarding vs references, always strive to use references, but there are things you can do only with ptrs, for example (there are many uses):
walking through elements in an array (e.g., marching over a standard array[])
when a called function allocates something & returns it via a ptr
Most importantly, pointers (and references, as opposed to automatic/stack-based & static objects) support polymorphism. A pointer to a base class may actually point to a derived class. This is fundamental to the OO behavior supported in C++.
First off, the question is wrong: the dilemma is not between pointers and stack, but between heap and stack. You can have an object on the stack and pass the pointer to that object. I assume what you are really asking is whether you should declare a pointer to class or an instance of class.
The answer is that it depends on what you want to do with the object. If the object has to exist after the control leaves the function, then you have to use a pointer and create the object on heap. You will do this, for example, when your function has to return the pointer to the created object or add the object to a list that was created before calling your function.
On the other hand, if the objects is local to the function, then it is better to use it on stack. This enables the compiler to call the destructor when the control leaves the function.
Which tutorials would those be? Actually, the rule is that you should use pointers only when you absolutely have to, which is quite rarely. You need to read a good book on C++, like Accelerated C++ by Koenig & Moo.
Edit: To clarify a bit - two instances where you would not use a pointer (string is being used here as an exemplar - same would go for any other type):
class Person {
public:
string name; // NOT string * name;
...
};
void f() {
string value; // NOT string * value
// use vvalue
}
You usually have to use pointers in the following scenarios:
You need a collection of objects that belong to different classes (in most cases they will have a common base).
You need a stack-allocated collection of objects so large that it'll likely cause stack overflow.
You need a data structure that can rearrange objects quickly - like a linked list, tree ar similar.
You need some complex logic of lifetime management for your object.
You need a data structure that allows for direct navigation from object to object - like a linked list, tree or any other graph.
In addition to points others make (esp. w.r.t. controlling the object lifetime), if you need to handle NULL objects, you should use pointers, not references. It's possible to create a NULL reference through typecasting, but it's generally a bad idea.
Generally use pointers / references to objects when:
passing them to other methods
creating a large array (I'm not sure what the normal stack size is)
Use the stack when:
You are creating an object that lives and dies within the method
The object is the size of a CPU register or smaller
I actually use pointers in this situation:
class Foo
{
Bar* bar;
Foo(Bar& bar) : bar(&bar) { }
Bar& Bar() const { return *bar; }
};
Before that, I used reference members, initialized from the constructor, but the compiler has a problem creating copy constructors, assignment operators, and the lot.
Dave
using pointers is connected with two orthogonal things:
Dynamic allocation. In general, you should allocate dynamically, when the object is intended to live longer that the scope in which it's created. Such an object is a resource which owner have to be clearly specified (most commonly some sort of smart pointer).
Accessing by address (regardless of how the object was created). In this context pointer doesn't mean ownership. Such accessing could be needed when:
some already existing interface requires that.
association which could be null should be modeled.
copying of large objects should be avoided or copying is impossible at all, but the reference can't be used (e.g., stl collections).
The #1 and #2 can occur in different configurations, for example you can imagine dynamically allocated object accessed by pointer, but such the object could also by passed by reference to some function. You also can get pointer to some object which is created on the stack, etc.
Pass by value with well behaved copyable objects is the way to go for a large amount of your code.
If speed really matters, use pass by reference where you can, and finally use pointers.
If possible never use pointers. Rely on pass by reference or if you are going to return a structure or class, assume that your compiler has return value optimization. (You have to avoid conditional construction of the returned class however).
There is a reason why Java doesn't have pointers. C++ doesn't need them either. If you avoid their use you will get the added benefit of automatic object destruction when the object leaves scope. Otherwise your code will be generating memory errors of various types. Memory leaks can be very tricky to find and often occur in C++ due to unhandled exceptions.
If you must use pointers, consider some of the smart pointer classes like auto_ptr. Auto destruction of objects is more than just releasing the underlying memory. There is a concept called RAII. Some objects require additionally handing on destruction. e.g. mutexes and closing files etc.
Use pointers when you don't want your object to be destroyed when the stack frame is emptied.
Use references for passing parameters where possible.
Speaking about C++, objects created on the stack cannot be used when the program has left the scope it was created in. So generally, when you know you don't need a variable past a function or past a close brace, you can create it on the stack.
Speaking about Qt specifically, Qt helps the programmer by handling a lot of the memory management of heap objects. For objects that are derived from QObject (almost all classes prefixed by "Q" are), constructors take an optional parameter parent. The parent then owns the object, and when the parent is deleted, all owned objects are deleted as well. In essence, the responsibility of the children's destruction is passed to the parent object. When using this mechanism, child QObjects must be created on the heap.
In short, in Qt you can easily create objects on the heap, and as long as you set a proper parent, you'll only have to worry about destroying the parent. In general C++, however, you'll need to remember to destroy heap objects, or use smart pointers.
In a C++ project that uses smart pointers, such as boost::shared_ptr, what is a good design philosophy regarding use of "this"?
Consider that:
It's dangerous to store the raw pointer contained in any smart pointer for later use. You've given up control of object deletion and trust the smart pointer to do it at the right time.
Non-static class members intrinsically use a this pointer. It's a raw pointer and that can't be changed.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to make a shared pointer to my class.
Given that, when is it ever appropriate for me to explicitly use a this pointer? Are there design paradigms that can prevent bugs related to this?
Wrong question
In a C++ project that uses smart pointers
The issue has nothing to do with smart pointers actually. It is only about ownership.
Smart pointers are just tools
They change nothing WRT the concept of ownership, esp. the need to have well-defined ownership in your program, the fact that ownership can be voluntarily transferred, but cannot be taken by a client.
You must understand that smart pointers (also locks and other RAII objects) represent a value and a relationship WRT this value at the same time. A shared_ptr is a reference to an object and establishes a relationship: the object must not be destroyed before this shared_ptr, and when this shared_ptr is destroyed, if it is the last one aliasing this object, the object must be destroyed immediately. (unique_ptr can be viewed as a special case of shared_ptr where there is zero aliasing by definition, so the unique_ptr is always the last one aliasing an object.)
Why you should use smart pointers
It is recommended to use smart pointers because they express a lot with only variables and functions declarations.
Smart pointers can only express a well-defined design, they don't take away the need to define ownership. In contrast, garbage collection takes away the need to define who is responsible for memory deallocation. (But do not take away the need to define who is responsible for other resources clean-up.)
Even in non-purely functional garbage collected languages, you need to make ownership clear: you don't want to overwrite the value of an object if other components still need the old value. This is notably true in Java, where the concept of ownership of mutable data structure is extremely important in threaded programs.
What about raw pointers?
The use of a raw pointer does not mean there is no ownership. It's just not described by a variable declaration. It can be described in comments, in your design documents, etc.
That's why many C++ programmers consider that using raw pointers instead of the adequate smart pointer is inferior: because it's less expressive (I have avoided the terms "good" and "bad" on purpose). I believe the Linux kernel would be more readable with a few C++ objects to express relationships.
You can implement a specific design with or without smart pointers. The implementation that uses smart pointer appropriately will be considered superior by many C++ programmers.
Your real question
In a C++ project, what is a good design philosophy regarding use of "this"?
That's awfully vague.
It's dangerous to store the raw pointer for later use.
Why do you need to a pointer for later use?
You've given up control of object deletion and trust the responsible component to do it at the right time.
Indeed, some component is responsible for the lifetime of the variable. You cannot take the responsibility: it has to be transferred.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to use my class.
Obviously, since the caller is not informed that the function will hide a pointer and use it later without the control of the caller, you are creating bugs.
The solution is obviously to either:
transfer responsibility to handle the lifetime of the object to the function
ensure that the pointer is only saved and used under the control of the caller
Only in the first case, you might end up with a smart pointer in the class implementation.
The source of your problem
I think that your problem is that you are trying hard to complicate matters using smart pointers. Smart pointers are tools to make things easier, not harder. If smart pointers complicate your specification, then rethink your spec in term of simpler things.
Don't try to introduce smart pointers as a solution before you have a problem.
Only introduce smart pointers to solve a specific well-defined problem. Because you don't describe a specific well-defined problem, it is not possible to discuss a specific solution (involving smart pointers or not).
While i don't have a general answer or some idiom, there is boost::enable_shared_from_this . It allows you to get a shared_ptr managing an object that is already managed by shared_ptr. Since in a member function you have no reference to those managing shared_ptr's, enable_shared_ptr does allow you to get a shared_ptr instance and pass that when you need to pass the this pointer.
But this won't solve the issue of passing this from within the constructor, since at that time, no shared_ptr is managing your object yet.
One example of correct use is return *this; in functions like operator++() and operator<<().
When you are using a smart pointer class, you are right that is dangerous to directly expose "this". There are some pointer classes related to boost::shared_ptr<T> that may be of use:
boost::enable_shared_from_this<T>
Provides the ability to have an object return a shared pointer to itself that uses the same reference counting data as an existing shared pointer to the object
boost::weak_ptr<T>
Works hand-in-hand with shared pointers, but do not hold a reference to the object. If all the shared pointers go away and the object is released, a weak pointer will be able to tell that the object no longer exists and will return you NULL instead of a pointer to invalid memory. You can use weak pointers to get shared pointers to a valid reference-counted object.
Neither of these is foolproof, of course, but they'll at least make your code more stable and secure while providing appropriate access and reference counting for your objects.
If you need to use this, just use it explicitly. Smart pointers wrap only pointers of the objects they own - either exclusivelly (unique_ptr) or in a shared manner (shared_ptr).
I personally like to use the this pointer when accessing member variables of the class. For example:
void foo::bar ()
{
this->some_var += 7;
}
It's just a harmless question of style. Some people like it, somepeople don't.
But using the this pointer for any other thing is likely to cause problems. If you really need to do fancy things with it, you should really reconsider your design. I once saw some code that, in the constructor of a class, it assigned the this pointer to another pointer stored somewhere else! That's just crazy, and I can't ever think of a reason to do that. The whole code was a huge mess, by the way.
Can you tell us what exactly do you want to do with the pointer?
Another option is using intrusive smart pointers, and taking care of reference counting within the object itself, not the pointers. This requires a bit more work, but is actually more efficient and easy to control.
Another reason to pass around this is if you want to keep a central registry of all of the objects. In the constructor, an object calls a static method of the registry with this. Its useful for various publish/subscribe mechanisms, or when you don't want the registry to need knowledge of what objects/classes are in the system.