tags:

views:

226

answers:

7

In brief, my question is about member variables as pointers in unmanaged C++.

In java or c#, we have "advanced pointer". In fact, we can't aware the "pointer" in them. We usually initialize the member of a class like this:

member = new Member();

or

member = null;

But in c++, it becomes more confusing. I have seen many styles: using new, or leave the member variable in stack.

In my point of view, using boost::shared_ptr seems friendly, but in boost itself source code there are news everywhere. It's the matter of efficiency,isn't it?

Is there a guildline like "try your best to avoid new" or something?

EDIT

I realize it's not proper to say "leave them in stack", here's a more proper way to say: when i need an object to be my member variable, should i prefer a object than a object*?

+15  A: 

The Boost source code is not a good example for how you should write your source code. The Boost libraries are designed to wrap up all the tedious, difficult, and error-prone code so that you don't have to worry about it in your code.

Your best bet is to follow two general rules in your code:

  • Don't use pointers where you don't need to use pointers
  • Where you do need to use pointers, use smart pointers (like shared_ptr or scoped_ptr)
James McNellis
+1 for "Don't use pointers where you don't need to use pointers"
Viktor Sehr
A: 

The benefit of using shared_ptr is that it is a "smart pointer" that does not require an explicit delete to free the memory. Otherwise, if you use new you will have to explicitly call delete to free the allocated memory once the object is no longer required.

Justin Ethier
A: 

You may want to use the C++ STL class "autoptr" to take care of managing your memory.

Also, in C++, if it is a member variable, it doesn't have to be a pointer.

class MyClass
{
    MyClass();

    MyMember a;
    MyMember* b;
    std::auto_ptr<MyMember> c;
}

MyClass::MyClass()
{
    // constructer
    // a is now instantiated -- I don't have to do anything
    b = new MyMember(); // I'll have to delete it in the destructor
    c.reset(new MyMember()); // I won't have to delete it in the destructor
}
Lyndsey Ferguson
Managing memory yourself is actually *not* a common paradigm in C++. **At all**. The whole point of C++ as opposed to C is to *not* manage memory yourself.
Konrad Rudolph
Are you thinking of Managed C++? Then, yes, your comment is correct. However, standard C++ provides new, delete, STL allocators all to assist you in your memory management tasks. The -1 on this post is misplaced.
Lyndsey Ferguson
@Lyndsey, to the contrary... in "managed C++" there is garbage collection, and so you can allocate things willy-nilly and not care about it. Because you have to manually deallocate anything that has been allocated, it is common C++ style to use smart pointers or RAII to automate allocation/deallocation, rather than manually allocate things (as that would require additional cleanup work).
Michael Aaron Safyan
@Michael A S, when you agree with someone, you don't write "to the contrary" :) Manager C++ does provide garbage collection, so you don't "have" to manage memory yourself as Konrad Rudolph writes unlike normal C++ where you often are managing it with new and delete, etc.
Lyndsey Ferguson
@Lyndsey, but I am disagreeing with you. Sure, C++ has the ability to manage memory yourself, but that doesn't mean it is common! C++ also supports the notion of Resource Acquisition Is Initialization (RAII), which allows allocation/deallocation to be automated via the use of reference-counting smart pointers. And that is far more common than explicitly using new/delete.
Michael Aaron Safyan
@Lyndsey, but Konrad is still correct. We may not have a garbage collector, but good C++ programmers don't need pointers that often (that's what the STL is for).
Brendan Long
@All: Thanks for the input. The code bases I've worked on are not using smart_ptrs and auto_ptrs typically. I'll update my comment to not specify that it is a common paradigm.
Lyndsey Ferguson
+8  A: 

Yes, there is a guideline - only use dynamic allocation when you must. A lot of the time yo can and should be using values, not pointers. For example, you should almost always be using:

vector <string> v;

rather than:

vector <string *> v;

and allocating the strings dynamically.

anon
A: 

In C++ it is a matter of choice to the developer. There is more power but also more responsibility that goes with it.

Example:

A class that declares an object with internal storage of arbitrary size.

  1. If you design this class to allocate worst case storage at instantiation you can avoid pointers altogether. But the cost is heavy in terms of memory usage for the average case.

  2. If you design the class to allocate memory based on its needs you might choose to use pointers. Then each instance will take only what it needs from the heap. But you must use care to avoid pointer bugs.

  3. If you design the class to allocate memory based on its needs you might still be able to avoid pointers using abstractions for the memory (i.e. auto_ptr or a custom buffer scheme, etc.).

So a guideline might be to explore the options available before resorting to naked pointers in application code. The balance might be different for library code since it will be more limited in scope, possibly more performance sensitive, and (hopefully) better tested.

Amardeep
+2  A: 

Certainly it won't kill you if you do a single new in the constructor, and a single delete in the destructor. In a simple case like that, using smart pointers is just pointless overhead.

If you go more complicated, or if you are paranoid about exception safety, smart pointers may very well be a good idea.

kotlinski