Sign in to follow this  
Decrius

[C++] Custom smart pointer with pointer to const?

Recommended Posts

I build a custom smart pointer for my ref. counting objects. I now however struggle to get things const-correct. The smart pointer is a templated class with 1 template value, which is the type of the pointer. Here's a cut-down definition of the class:
    template <class T>
    class Pointer
    {
    public:
        ...

        ////////////////

        bool operator == (const T *pointer) const;
        bool operator != (const T *pointer) const;
        bool operator < (const T *pointer) const;
        bool operator > (const T *pointer) const;

        ...

        ////////////////

        operator T *() const;
        // operator const T *() const; // removed, because it cannot be overloaded with the above when T is const itself.

        T &operator * () const;
        T *operator -> () const;

    protected:
        T *_pointer;
    };
And sample code:
class Foo: public Object // Pointer relies on Object
{
};

typedef Pointer<Foo> FooPointer;
typedef Pointer<const Foo> ConstFooPointer;

void f(const FooPointer &foo)
{
}

void g(const ConstFooPointer &const_foo)
{
}

FooPointer foo;
ConstFooPointer const_foo;

f(foo);
f(const_foo);
g(foo);
g(const foo);
Look at the Pointer definition, how weird is it to have 'const T' when T is for example 'const Foo', resulting in 'const const Foo'? Must I build a Pointer class for regular pointers, and one for pointer-to-const pointers? Or must I use template specialization? Or should I make it work for both, and how? Could someone point me in the right direction? Perhaps a brief example? Thanks!

Share this post


Link to post
Share on other sites
T is your type. There is no need for const T.

It's also a promise you cannot keep.

Consider:
Foo * foo; // non const

Pointer<const Foo> fooPtr(foo); // this fails


By consequence, without resorting to forcing casts, if Pointer points to const, there is no way it could ever be tested for (in)equality against a non-const.

Also:
	const Foo * foo = new Foo();
Pointer<Foo> fooptr(foo); // fails - we cannot be non-const to const pointer


Hence there is no need to solve a problem that doesn't exist.

So using T is enough:
        bool operator == (T *pointer) const;
bool operator != (T *pointer) const;

Share this post


Link to post
Share on other sites
@rip-off
No, I find Boost very unreadable, I did take a look at auto_ptr from Scott Meyer, but it doesn't focus on mimicking a pointer, which I do try to do.

@Antheus
Interesting thoughts, thank you.
This kind of material is prone to brain-farts, but very useful in understanding the language thoroughly :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
@rip-off
No, I find Boost very unreadable, I did take a look at auto_ptr from Scott Meyer, but it doesn't focus on mimicking a pointer, which I do try to do.

You don't need to read the source code. For example, the synopsis shows the interface, which is all you would need.

Share this post


Link to post
Share on other sites
Quote:
No, I find Boost very unreadable
Like rip-off said, there's no need to read the source code, unless you're curious about the inner workings.

Anyway, from what I've seen at least, the code for the Boost smart pointer classes is no more difficult to read than that of your typical standard library implementation. SC++L code can be pretty difficult to read as well, but that usually doesn't stop people from using it.

(Also, at least some of the Boost smart pointers have been incorporated into the new C++ standard. If your implementation includes them, using them is really just as straightforward as using any other part of the standard library.)

Share this post


Link to post
Share on other sites
Thanks rip-off, didn't thought of that :O

Quote:
Original post by jyk
Quote:
No, I find Boost very unreadable
Like rip-off said, there's no need to read the source code, unless you're curious about the inner workings.

Anyway, from what I've seen at least, the code for the Boost smart pointer classes is no more difficult to read than that of your typical standard library implementation. SC++L code can be pretty difficult to read as well, but that usually doesn't stop people from using it.

(Also, at least some of the Boost smart pointers have been incorporated into the new C++ standard. If your implementation includes them, using them is really just as straightforward as using any other part of the standard library.)


Yes, Boost/SC++L code is often great to use, it's just terrible to read to get to know how it works.
The reason I implemented my own was to make it nicely fit with the design, and I think it gives you some C++-fu ;)

I fixed the Pointer code, less duplication now too, and works well with const. Thanks guys!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this