CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347

    How to encapsulate the "Creation through smart pointers" only interface

    I have a series of classes whose creation interface I'd like to be
    a static create() function which returns a smart pointer to an
    object of the class. I don't want the users creating objects by
    themselves so I have made the constructors protected.
    Here's a brief example:
    Code:
    class TestClass
    {
    public:
       typedef boost::shared_ptr<TestClass> Ptr;
       static Ptr create();
    
    private: // protected if set up for inheritance
       TestClass()
       // etc
       Ptr someDataThatIsOfTypePtr;
    };
    I may want to add a clone() function or a virtual destructor, but
    that is all something that can be discussed later. The problem is
    that I have to repeat all of this code for all classes that I want
    this interface for. So, I came up with a "wrapper" template for
    this sort of thing:

    Code:
    template <typename T>
    class SharedPtr
    {
    public:
       typedef boost:shared_ptr<T> Ptr;
       static Ptr create() { return Ptr(new T); }
    };
    If I want TestClass to benefit from this, TestClass has to derive
    from SharedPtr<TestClass> because TestClass internally needs
    the Ptr typedef [I don't want to have to repeat all of that]. After
    I inherit, SharedPtr doesn't even have access to the constructor
    [because it's protected/private] so I wind up having to make
    SharedPtr a friend. This doesn't seem right; there has to be a
    better way.

    So ... what the heck should I be doing in order to make an object
    creatable only with a smart pointer interface? I'm sure that I've
    seen something like this in the past on this site, but a search
    proved to be fruitless.

    If anybody needs any more details, I will be happy to provide
    them.

    --Paul

  2. #2
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Paul: I think you're actually better off accepting the pain of repeating the code each time. The problem you have with trying to make a general solution is the same that class like ScopeGuard suffers from: annoying class functions (or ctors in your case) that want different numbers of arguments.

    Given the SharedPtr you just defined, what do you do with classes that don't have a default ctor? You're going to end up defining all sorts of templated create() functions for varying numbers of arguments. And, of course, you've no way of propagating any default arguments to the create(0 function either, so people have got to explicitly state defaults.

    On the whole, I'd leave the create() in the class that's being created where it can be tailored to fit. It's also cleaner. ScopeGuard is OK because it's so useful that you can accept the less-than-trivial implementation, but in your case I'd go for the K.I.S.S. approach.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  3. #3
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Thanks a lot for your advice, Graham. I wish that I could come up
    with something a little better, but you're right in that it could
    potentially be a maintenance nightmare.

    Also, I did a quick search on Google and found ScopeGuard to be
    something that Andrei Alexandrescu posted on C++ Users
    Journal. Is this the class you were referring to? If so, there is no
    need to reply; no news is good news

    --Paul

  4. #4
    Join Date
    Sep 2002
    Posts
    1,747
    I wouldn't be too afraid of the friend in this case. It's not as scary a coupling as the normal use of friend across unrelated types since you would be already using the "curiously recurring template pattern" to provide a form of reverse inheritance coupling, and the headers would already be linked in the translation unit. So it would seem that friend would be exactly what you need to wrap up your creation management idiom nicely.

    However, what Graham hath spoken is gospel. It would seem like you may want to use such a creation management system throughout your application's design, and then you run into all sorts of problems in trying to make general a problem that is specific to the ctor's signature and defaults. This makes it very hard to reuse code in a completely generic fashion. However, I normally find that any particular hierarchy of mine normally maintains the same ctor signature and defaults throughout that hierarchy (in fact, I often enforce that as a personal rule because it keeps my hierarchies minimal and is a great indicator for when delegation should replace inheritance). If this is the case in your application as well, there is certainly the possibility for using hierarchy-wide traits to tell you which creation wrapper to use. You then can build up creation wrappers for much larger pieces of your application, and get at least some degree of code reuse...
    */*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/

    "It's hard to believe in something you don't understand." -- the sidhi X-files episode

    galathaea: prankster, fablist, magician, liar

  5. #5
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Thank you, galathea, for your input. A lot of my constructors are,
    in fact, similar, but there are some objects who need to be
    constructed a little bit differently. I think I'm going to have to
    follow the KISS principle ... but at least I'm qualified to do that

    --Paul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured