Preserve access privileges when using ‘->’ operator

  access-protection, c++, pointers

I have two classes,

template<class Type>
class SafePtr {
public:
    SafePtr() {}
    ~SafePtr() {}

    void Lock(Type* data, void* key)
    {
        if (!pKey)
        {
            pKey = key;
            pData = data;
        }
    }

    Type* Unlock(void* key) const
    {
        if (key == pKey)
            return pData;
    }

    Type* operator->() 
    {
        return pData;
    }

private:
    Type* pData = nullptr;
    void* pKey = nullptr;
};

template<class Type>
class SafePtrArray {
public:
    SafePtrArray() {}
    ~SafePtrArray() {}

    template<class... Args>
    SafePtr<Type> CreatePtr(Args&&... args)
    {
        Type* data = new Type(args...);
        ptrs.insert(ptrs.end(), data);

        SafePtr<Type> ptr;
        ptr.Lock(data, this);
        return ptr;
    }

    Type* UnlockPtr(const SafePtr<int>& ptr)
    {
        return ptr.Unlock(this);
    }

    void Destroy(const SafePtr<int>& ptr)
    {
        Type* pointer = ptr.Unlock(this);

        for (auto itr = ptrs.begin(); itr != ptrs.end(); itr++)
        {
            if ((*itr) == pointer)
            {
                delete pointer;
                ptrs.erase(itr);
            }
        }
    }

private:
    std::vector<Type*> ptrs;
};

Explanation:
The goal is to protect a pointer so that the user can access its members but not get to manipulate its actual pointer (mainly delete it prematurely). And also I need to store all the pointers in an array so that when the parent object destroys, I can automatically destroy all the allocated pointers.
For this I use two classes, SafePtr and SafePtrArray. SafePtrArray creates and stores the pointers and wraps them in the SafePtr and returns it to the user. SafePtr is just a wrapper and should not let the user get access to the underlying pointer but will allow them to access its members.

It works fine at first but soon I found this error,

int main()
{
    SafePtrArray<int> ptr;
    auto pInt = ptr.CreatePtr();
    int* i = pInt.operator->();     // Users can get access to the underlying pointer using this.

    ptr.Destroy(pInt);
}

So my question is,
Is there a way to prevent users from getting access to the underlying type and prevent them from manipulating the pointer while having the privilege to access its members?

Source: Windows Questions C++

LEAVE A COMMENT