Skip to main content
deleted 2 characters in body; added 347 characters in body
Source Link
Andrew
  • 143
  • 1
  • 5
  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any implicit memory allocation/deallocation (it provides accessa method to delete the base pointer when that time comesto the object)
  • When compared to another wrapper object, it compares their pointers to see if they are the same
template <class PtrType, class LockType>
class ELockWrapper {
public:
    class Proxy {
    public:
        Proxy(PtrType* p, LockType* lock) : ptr(p), mLock(lock)  { mLock->Lock(); }
        ~Proxy()                                                 { mLock->Unlock(); }
        PtrType* operator->()                                    { return ptr; }
        PtrType  operator*()                                     { return *ptr; }
    private:
        PtrType*    ptr;
        LockType*   mLock;
    };

    ELockWrapper()                            : ptr(nullptr), lock(nullptr) {}
    ELockWrapper(nullptr_t t)                 : ELockWrapper()   {}
    ELockWrapper(PtrType *p, LockType* l)     : ptr(p), lock(l)  {}
    ELockWrapper(PtrType *p, LockType& l)     : ptr(p), lock(&l) {}
    ELockWrapper(const ELockWrapper& copy) = default;

    ELockWrapper& operator=(const ELockWrapper& x) = default;
    bool operator==(const ELockWrapper& cmp) { return cmp.ptr == ptr; }
    bool operator!=(const ELockWrapper& cmp) { return !operator==(cmp); }
    bool operator==(PtrType* t)              { return ptr == t; }
    bool operator!=(PtrType* t)              { return ptr != t; }
    bool operator==(bool b)                  { return (ptr && b) || (!ptr && !b); }
    bool operator!=(bool b)                  { return !operator==(b); }
    operator bool() const                    { return ptr; }

    Proxy operator->() {
        return Proxy(ptr, lock);
    }

    PtrType operator*() {
        return *Proxy(ptr, lock);
    }
    
    PtrType*void GetPointerDelete() {
        Proxy(ptr, lock);
        returndelete ptr;
    }

private:
    PtrType*    ptr;
    LockType*   lock;
};

Any mistakes/suggestions would be much appreciated.

One quick thing I want to ask: if ANY of the methods on ELockWrapper can be called concurrently, should I wrap each overloaded boolean operator with a lock? I'm thinking perhaps the delete method will be called, which a thread was interrupted in one of the operators might be problematic. Just a confirmation if this is the right thing to do?

  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any memory allocation/deallocation (it provides access to the base pointer when that time comes)
  • When compared to another wrapper object, it compares their pointers to see if they are the same
template <class PtrType, class LockType>
class ELockWrapper {
public:
    class Proxy {
    public:
        Proxy(PtrType* p, LockType* lock) : ptr(p), mLock(lock)  { mLock->Lock(); }
        ~Proxy()                                                 { mLock->Unlock(); }
        PtrType* operator->()                                    { return ptr; }
        PtrType  operator*()                                     { return *ptr; }
    private:
        PtrType*    ptr;
        LockType*   mLock;
    };

    ELockWrapper()                            : ptr(nullptr), lock(nullptr) {}
    ELockWrapper(nullptr_t t)                 : ELockWrapper()   {}
    ELockWrapper(PtrType *p, LockType* l)     : ptr(p), lock(l)  {}
    ELockWrapper(PtrType *p, LockType& l)     : ptr(p), lock(&l) {}
    ELockWrapper(const ELockWrapper& copy) = default;

    ELockWrapper& operator=(const ELockWrapper& x) = default;
    bool operator==(const ELockWrapper& cmp) { return cmp.ptr == ptr; }
    bool operator!=(const ELockWrapper& cmp) { return !operator==(cmp); }
    bool operator==(PtrType* t)              { return ptr == t; }
    bool operator!=(PtrType* t)              { return ptr != t; }
    bool operator==(bool b)                  { return (ptr && b) || (!ptr && !b); }
    bool operator!=(bool b)                  { return !operator==(b); }
    operator bool() const                    { return ptr; }

    Proxy operator->() {
        return Proxy(ptr, lock);
    }

    PtrType operator*() {
        return *Proxy(ptr, lock);
    }
    
    PtrType* GetPointer() {
        Proxy(ptr, lock);
        return ptr;
    }

private:
    PtrType*    ptr;
    LockType*   lock;
};

Any mistakes/suggestions would be much appreciated.

  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any implicit memory allocation/deallocation (it provides a method to delete the pointer to the object)
  • When compared to another wrapper object, it compares their pointers to see if they are the same
template <class PtrType, class LockType>
class ELockWrapper {
public:
    class Proxy {
    public:
        Proxy(PtrType* p, LockType* lock) : ptr(p), mLock(lock)  { mLock->Lock(); }
        ~Proxy()                                                 { mLock->Unlock(); }
        PtrType* operator->()                                    { return ptr; }
        PtrType  operator*()                                     { return *ptr; }
    private:
        PtrType*    ptr;
        LockType*   mLock;
    };

    ELockWrapper()                            : ptr(nullptr), lock(nullptr) {}
    ELockWrapper(nullptr_t t)                 : ELockWrapper()   {}
    ELockWrapper(PtrType *p, LockType* l)     : ptr(p), lock(l)  {}
    ELockWrapper(PtrType *p, LockType& l)     : ptr(p), lock(&l) {}
    ELockWrapper(const ELockWrapper& copy) = default;

    ELockWrapper& operator=(const ELockWrapper& x) = default;
    bool operator==(const ELockWrapper& cmp) { return cmp.ptr == ptr; }
    bool operator!=(const ELockWrapper& cmp) { return !operator==(cmp); }
    bool operator==(PtrType* t)              { return ptr == t; }
    bool operator!=(PtrType* t)              { return ptr != t; }
    bool operator==(bool b)                  { return (ptr && b) || (!ptr && !b); }
    bool operator!=(bool b)                  { return !operator==(b); }
    operator bool() const                    { return ptr; }

    Proxy operator->() {
        return Proxy(ptr, lock);
    }

    PtrType operator*() {
        return *Proxy(ptr, lock);
    }
    
    void Delete() {
        Proxy(ptr, lock);
        delete ptr;
    }

private:
    PtrType*    ptr;
    LockType*   lock;
};

Any mistakes/suggestions would be much appreciated.

One quick thing I want to ask: if ANY of the methods on ELockWrapper can be called concurrently, should I wrap each overloaded boolean operator with a lock? I'm thinking perhaps the delete method will be called, which a thread was interrupted in one of the operators might be problematic. Just a confirmation if this is the right thing to do?

added 1 character in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

HereHere is it in action with some test cases:

https://ideone.com/zlcnSC.

Here is it in action with some test cases:

https://ideone.com/zlcnSC

Here is it in action with some test cases.

added 100 characters in body
Source Link
Andrew
  • 143
  • 1
  • 5
  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any memory allocation/deallocation (it provides access to the base pointer when that time comes)
  • When compared to another wrapper object, it compares their pointers to see if they are the same
  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any memory allocation/deallocation (it provides access to the base pointer when that time comes)
  • It cannot be implicitly converted to the pointer type it is pointing to
  • It does not handle any memory allocation/deallocation (it provides access to the base pointer when that time comes)
  • When compared to another wrapper object, it compares their pointers to see if they are the same
deleted 18 characters in body; edited tags; edited title
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Loading
Source Link
Andrew
  • 143
  • 1
  • 5
Loading