Thread: Smart pointer questions

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Smart pointer questions

    OK, so consider the following situations:

    1) I have an object X who owns its own resources (via pointers). It creates these resources itself and also gives access to these resources through a public interface. Therefore, the pointers in the class should be shared_ptr and return weak_ptr, right?
    I know shared_ptr means shared ownership, but it's also the only pointer from which you can return a non-owning, observing pointer. Would there actually be a need for another type of pointer such as scoped_ptr that explicitly owns ownership, but allows non-intrusive, non-owning pointers to it to be returned?

    2) I have an object X which should own its own resources. However, it does not create these resources, instead relying on others to pass in the resources, and the assuming ownership of these resources. Is this right? Should the creator of the resources assume ownership and lend non-owning pointers to the object X?
    So far as I can tell, there is no way for object X to acquire ownership properly.
    A weak_ptr cannot be initialized with a new resource, so object X cannot accept a weak_ptr to the resource unless the one who passes the resource owns, or shares, the ownership (in other words, uses a shared_ptr). And a weak_ptr cannot be assigned to a shared_ptr or scoped_ptr either. So how does one usually do this? Is the design flawed?

    3) I have a resource in another class which I shall hand to class X for storing. The resource is a non-pointer, so a reference is passed to class X. Then class X needs to store a pointer to this resource it is passed. I don't like the idea of using a raw pointer because it could be confused to a pointer which needs to be deleted. So, I made a simple do_not_delete container and wrapped it inside. Is this a good solution? Is there any smart pointers for this purpose?

    Appreciate any and all answers.
    Last edited by Elysia; 03-13-2009 at 12:05 PM.
    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.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Therefore, the pointers in the class should be shared_ptr and return weak_ptr, right?
    I'd say that that is probably the correct path, but really it depends on the intent of the interface.

    Would there actually [...] to it to be returned?
    O_o

    How would you manage this without using the same pattern as 'shared_ptr'/'weak_ptr'? It would be cheaper, but beyond that?!

    Should the creator of the resources assume ownership and lend non-owning pointers to the object X?
    No. You may change the design in other ways if you wish, but if the object should own a resource, it is almost certainly going to be useless if associated with an unavailable resource. It would seem pointless for the 'pipe' to exist without a 'pipe_buffer' if the 'pipe' exists solely to write to the 'pipe_buffer'.

    So far as I can tell, there is no way for object X to acquire ownership properly.
    You should not be afraid of 'auto_ptr'/'unique_ptr' and friends--with 'unique_ptr' the obvious preference. (This interface naturally implies, and almost requires, that the object will obtain ownership.)

    So how does one usually do this?
    I use one of the possible library implementation of 'move' semantics. (My implementation is spitting distance from being a C++0x compatible 'unique_ptr'.)

    Is the design flawed?
    How are we supposed to know? This is like asking: "Is the 'Singleton' pattern flawed?". It is the mechanic that makes the design fit or unfit for a particular purpose.

    Is this a good solution?
    Yes. No. Maybe. I don't like it. It isn't verbose; it doesn't explain the situation.

    Is there any smart pointers for this purpose?
    Pass a "null deleter" to any of the new smart pointers that support "custom deleters"--my vote for 'shared_ptr' as it would lend context.

    Soma
    Last edited by phantomotap; 03-13-2009 at 12:46 PM.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    O_o
    First time I do understand what you say.
    Yay!

    OK, some context might be good then.
    I am thinking of something like this...
    First, a class that demonstrates many of the questions I ask. Class BodyPart (some unrelevant parts cut):

    Code:
    	class BodyPart
    	{
    	public:
    		BodyPart(const std::tr1::shared_ptr<Texture>& tex, float gPoint_x, float gPoint_y);
    		virtual ~BodyPart();
    
    	private:
    		Coordinates m_coord;
    		std::tr1::shared_ptr<Texture> m_tex;
    		hgeSprite m_spr;
    		GluePoint gPoint;
    	};
    2) BodyPart is supposed to be a generic class for "body parts" of a sprite. Hence, it wants a texture. Since it's generic, it doesn't create the texture, but rather accepts it from the user and creator of the class.
    The idea is that BodyPart shall own the texture because it's the one that will operate and use the texture. Once the body part is destroyed, so shall its associated texture be, too.
    So what type should BodyPart's constructor accept? And what type should it store among its members?

    1) Assume, for a second, that BodyPart could allow outside access to its texture. Since BodyPart owns the texture (or should), we don't want to return a shared_ptr since that would indicate shared ownership (plus the chance that the texture might outlive its owner). So what type should BodyPart return then, if this was possible? weak_ptr?

    3) First, an example:
    Code:
    class GluePoint
    {
    public:
    	virtual void Connect(GluePoint& point);
    
    private:
    	no_delete_ptr<GluePoint> partner;
    };
    GluePoint is instantiated as seen above, as a member of the BodyPart class.
    It needs to communicate with another GluePoint and thus it wants to "connect" to it, and store a pointer to that other instance of GluePoint.
    Because the other GluePoint will also be located inside a BodyPart, they are not created on the heap and thus cannot be deleted.
    GluePoint just wants to acquire a non-owning instance (because it doesn't own its "partner" nor should it destroy it). I solved it by using a no_delete_ptr, which is basically just a thin wrapped around a pointer, but the name of the container is supposed to give a message: do not delete this pointer.
    Implementation:
    Code:
    void GluePoint::Connect(GluePoint& point)
    {
    	partner = &point;
    }
    So what type should GluePoint::Connect accept, and possibly what type should it store to make a connection like this possible? That is my question.

    I won't say this design is flawless or good, just the way it is now, and I'm scrambling for ideas on how to manage ownership.
    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.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    First time I do understand what you say.
    I've been sick; I'm running about +3F.

    So what type should BodyPart's constructor accept?
    'BodyPart(std::unique_ptr<Texture>, float, float);'

    This signature forces the client to use a specific method of creation.

    And what type should it store among its members?
    Because 'BodyPart' assumes ownership of the texture created by the client source, you may store the texture however you like.

    So what type should BodyPart return then, if this was possible?
    A method returning a 'weak_ptr' is truly fine, but that limits your storage options to 'shared_ptr'. Also, once I have a 'weak_ptr' I can create a 'shared_ptr' so a texture living beyond the 'BodyPart' object would still be a concern.

    I'd probably just return a reference. (I don't care for the absurdity of complicating a design solely because the simple approach isn't "OOP" enough.)

    So what type should GluePoint::Connect accept, and possibly what type should it store to make a connection like this possible?
    There is nothing wrong with what you've done; I just don't like it. Technically, it limits feature options a bit, but then I don't know that 'GluePoint' isn't final.

    I'd probably just use a 'weak_ptr<GluePoint>' and give the associated 'shared_ptr<?>' a "null deleter" for such local objects.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM