Thread: std::tr1::shared_ptr question

  1. #1
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168

    std::tr1::shared_ptr question

    How can I add a shared_ptr to a container of shared_ptrs of some existing object?

    Example of what I'm trying to accomplish here:
    Code:
    
    #include <algorithm>
    #include <iostream>
    #include <memory>
    #include <vector>
    
    class Foo{};
    
    int main()
    {
    	std::vector<Foo> foos;
    	foos.push_back(Foo());
    	foos.push_back(Foo());
    	foos.push_back(Foo());
    
    	std::vector<std::tr1::shared_ptr<Foo>> fooPointers;
    
    	std::for_each
    	(
    	    foos.begin(), foos.end(),
    		[&fooPointers](Foo foo)
    		{
    			fooPointers.push_back( /* How do I add an existing foo as a shared_ptr here? */ );
    		}
    	);
    
    	return 0;
    }
    goto( comeFrom() );

  2. #2
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    IMO, you shouldn't. shared_ptr assumes that it has ownership of the object it points to. You can either make sure your objects are never stored outside of a shared_ptr or make a new copy of your object so that the copy is managed by the shared_ptr.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  3. #3
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Ok, cool. Here's the example revised, but is there a way to eliminate the ugly cast where the Foo objects are first created?

    Code:
    
    #include <algorithm>
    #include <iostream>
    #include <memory>
    #include <vector>
    
    class Foo{};
    
    int main()
    {
    	std::vector<std::tr1::shared_ptr<Foo>> foos;
    	foos.push_back((std::tr1::shared_ptr<Foo>)new Foo());
    	foos.push_back((std::tr1::shared_ptr<Foo>)new Foo());
    	foos.push_back((std::tr1::shared_ptr<Foo>)new Foo());
    
    	std::vector<std::tr1::shared_ptr<Foo>> fooPointers;
    
    	std::for_each
    	(
    	    foos.begin(), foos.end(),
    		[&fooPointers](std::tr1::shared_ptr<Foo> foo)
    		{
    			fooPointers.push_back(foo);
    		}
    	);
    
    	return 0;
    }
    goto( comeFrom() );

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by StainedBlue
    is there a way to eliminate the ugly cast where the Foo objects are first created?
    Instead of using a C-style cast, use the appropriate constructor directly, though this would involve a mere shifting of parentheses and can be regarded as changing to use a function-style cast
    Quote 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.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    What pianorain is getting at is that when the shared pointer goes out of scope the vector has no way of knowing this and will now have a pointer to an area of memory that has been cleaned up. The pointer must be removed from the vector and the only way to do this is to either notify the container of the event or choose a different design.

  6. #6
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by Bubba View Post
    What pianorain is getting at is that when the shared pointer goes out of scope the vector has no way of knowing this and will now have a pointer to an area of memory that has been cleaned up. The pointer must be removed from the vector and the only way to do this is to either notify the container of the event or choose a different design.
    Thanks. Yea I guess my original confusion was more to do with what a shared_ptr did. I originally thought of it more as a managed pointer, than a managed object (hence the syntactic error in my original post). In my case, rewriting the original containers as containers of shared_ptrs was no big deal, and literally took me seconds to rewrite.

    @laserlight

    yea the cast i posted is definitely silly, and a quick google of shared_ptr got me a quick tutorial of its consttructor. Thanks.
    goto( comeFrom() );

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    In my case, rewriting the original containers as containers of shared_ptrs was no big deal, and literally took me seconds to rewrite.
    Eh? I don't follow.

  8. #8
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by Bubba View Post
    Eh? I don't follow.
    In my OP, i had a vector of foos, which i was trying to "convert" to shared_ptrs for the "fooPointers" vector (a vector of shared_ptrs).

    in my second post, i changed the original vector, to a vector of shared_ptrs as well, eliminating the need for a conversion between an already owned object, and a shared_ptr (which assumedly can't be done).

    laserlight pointed out that the cast was indeed in bad taste, and suggested I simply use the shared_ptr constructor instead.
    goto( comeFrom() );

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    On a side note, if you need a shared_ptr referring to an object that it doesn't own, you can give the shared_ptr a null deleter.
    Code:
    std::shared_ptr<Foo> ptr(&foo, [](Foo*){});
    Also, since you're using lambdas, you apparently have an 0x-enabled compiler, so you should be able to use std::shared_ptr directly; no need to go the tr1 route. Perhaps your compiler even provides make_shared, which would make the code prettier:
    Code:
    std::vector<std::shared_ptr<Foo>> foovec;
    foovec.push_back(std::make_shared<Foo>());
    It's also slightly more efficient.

    If you don't actually need shared ownership, though, I would strongly recommend using a boost:tr_vector instead of a vector of shared_ptrs. I find its interface to be much more convenient.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by CornedBee View Post
    On a side note, if you need a shared_ptr referring to an object that it doesn't own, you can give the shared_ptr a null deleter.
    Code:
    std::shared_ptr<Foo> ptr(&foo, [](Foo*){});
    Also, since you're using lambdas, you apparently have an 0x-enabled compiler, so you should be able to use std::shared_ptr directly; no need to go the tr1 route. Perhaps your compiler even provides make_shared, which would make the code prettier:
    Code:
    std::vector<std::shared_ptr<Foo>> foovec;
    foovec.push_back(std::make_shared<Foo>());
    It's also slightly more efficient.

    If you don't actually need shared ownership, though, I would strongly recommend using a boost:tr_vector instead of a vector of shared_ptrs. I find its interface to be much more convenient.
    All very nice suggestions. Thank you. The make_shared make things a lot cleaner.
    goto( comeFrom() );

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Lambdas, while very cool, have some of the ugliest syntax I've ever seen.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think they look fine. You may need to "prettify" the source code when using them, though, or it may end up looking like crap. I mean, they're pretty much native function syntax.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by Bubba View Post
    Lambdas, while very cool, have some of the ugliest syntax I've ever seen.
    While just a matter of opinion, I agree c++ lambdas are hideous when you compare them to say c# lambdas. But the syntax is growing on me slowly.
    goto( comeFrom() );

  14. #14
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Just thought I'd share this link of shared_ptr programming techniques. The article includes the null deleter technique CornedBee pointed out.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question about a question
    By hausburn in forum C++ Programming
    Replies: 3
    Last Post: 04-25-2010, 05:24 AM
  2. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  3. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM