views:

421

answers:

5

Well I know there are good topics about smart pointers, but since I'm starting to use them extensively I want to know some recommendations on bad or dangerous uses, e.g:

  • Raw-pointer conversions
  • Smart pointers to references/References to smart pointers
  • etc.

Thank you in advance.

(Added)

Suppose I've a class A with pointers to B as members, I can specify them as B* (raw-ptr) or as shared_ptr members.

class A
{
    B* ptr_b;
    shared_ptr<B> s_ptr_b;
}

If I don't understood bad,

ptr_b = new (B); // raw pointer of course
ptr_b = shared_ptr<B>(new B)   ; // safe, ownership to shared_ptr
s_ptr_b = new (B); // unsafe due to conversion from B* to shared_ptr<B>
s_ptr_b = shared_ptr<B>(new B)   ; // also safe, equal to case II?

[Added more...]

  • Altough user Joe posted that the 3rd conversion was safe (X* to shared_ptr<X>), it's not safe and it is forbidden.

I'm left with some advices regarding:

  • Passing shared_ptr<X> to functions expecting X*

  • If X* x = shared_ptr<X>(new X) equals to shared_ptr<X> x = shared_ptr<X>(new X).

  • Interaction between references and shared_ptr<>.

Thank you very much.

+3  A: 

If you're using STL, never create containers of auto_ptr.

Technically, it shouldn't even compile but many platforms will not generate errors when compiling containers of auto_ptr.

17 of 26
The reason is many many compiler engineers decided that this was sensible and so made it work on their version of the standard library. It is nonportable though (too bad)...
Joshua
Actually, it's not sensible given the semantics of auto_ptr and is, in fact, illegal according to the specification. Microsoft actually updated their library to be compliant with the spec. More info: http://www.gotw.ca/gotw/025.htm and http://www.aristeia.com/BookErrata/auto_ptr-update.html
17 of 26
+2  A: 

Don't use arrays with auto_ptr and shared_ptr, because these classes cannot delete arrays correctly.

Oleg Yaroshevych
+2  A: 

It's dangerous to use smart pointers that allow implicit conversions together with lagacy APIs that use raw pointers. Yasper is one of them. It allows the following:

void f(yasper::ptr<foo> p) {
    // ...
}

int main() {
    foo * p = new foo;
    f(p); // thinking it accepts foo*
    p->doit(); // oops, it's deleted!
    delete p; // already done by yasper::ptr !
}

Good that boost::shared_ptr doesn't allow that :)

Johannes Schaub - litb
I'm using Yasper, seems it allows dangerous practices.
Hernán
yeah, i remember that thread where we talked about that :)
Johannes Schaub - litb
Right! So I was correct in my example of shared_ptr<CLASS> c = new CLASS which is not allowed, but Joe said it's "normal usage". All right, raw->shared forbidden, shared.get()->raw allowed (this is safe if scope where conversion is done does not store a ref, I think).thank you for your help.
Hernán
+1  A: 

You have this muddled.

ptr_b = new (B); // raw pointer of course
ptr_b = shared_ptr<B>(new B)   ; // illegal, boost::shared_ptr should prevent this
s_ptr_b = new (B); // No automatic conversion in the boost::shared_ptr library
s_ptr_b = shared_ptr<B>(new B)   ; // explicit constructor and lack of operator=(T*) make this required.
jmucchiello
You're right, second line is totally incorrect: it is cast from shared pointer to raw pointer -- should use .get()
Hernán
Mmm, i think example III is not allowed, i've testedshared_ptr<X> ptr_x = new X;Compiler says X* cannot be converted to shared_ptr<X>.
Hernán
You're right. I don't use boost library often and just assumed. I fixed the answer.
jmucchiello