1

I was trying to implement a simplified version of shared_ptr. But during compiling time, the compiler popped out an error of using undeclared identifier. However, I did declare the variable.

Can somebody help me to figure out why? Thanks in advance.

The code is as below:

template <typename T>
class S_ptr
{
// private classes definition
private:
    template <typename T2>
    class DefaultDeleter
    {
    public:
        void operator()(T2* p) { delete p; }
    };

    class Aux
    {
        template<typename> friend class S_ptr;
    public:
        // constructor & destructor
        Aux() : ref_count_(1) {}

        virtual ~Aux() {}

        // member method
        virtual void incre() { ++ref_count_; }
        virtual void decre() = 0;
        virtual void destroy() = 0;

    protected:
        unsigned int ref_count_;  // UNDECLARED IDENTIFIER
    };

    template <typename T2, typename Deleter>
    class AuxCounter : public Aux
    {
    public:
        // constructor & destructor
        AuxCounter(T2* p, Deleter d) : ptr_(p), deleter_(d) {}

        ~AuxCounter() { decre(); }

        // member method
        void decre() override { if(--ref_count_ == 0) destroy(); } // ERROR 
        void destroy() override { deleter_(ptr_); }

        //public member
        T2* ptr_;
    private:
        Deleter deleter_;
    };
    // private class defination end

public:
    // constructor & destructor
    S_ptr(T* p) : ptr_(new T(*p))
    {
        counter_ = new AuxCounter<T, DefaultDeleter<T>>(ptr_,     DefaultDeleter<T>());
        delete p;
        p = nullptr;
    }
    template <typename T2, typename D> S_ptr(T2* p, D&& deleter) :     ptr_(new T(*p))
    {
        counter_ = new AuxCounter<T, D>(new T(*p), deleter);
        delete p;
        p = nullptr;
    }
    S_ptr(S_ptr<T>& rhs) : ptr_(rhs.ptr_), counter_(rhs.counter_) { counter_->incre(); }

    ~S_ptr() { delete counter_; }

    // assignment
    S_ptr& operator=(const S_ptr<T>& rhs)
    {
        auto temp = rhs.counter_;
    temp->incre();
    counter_->decre();
    counter_ = temp;
    ptr_ = rhs.ptr_;
    return *this;
}
// ..........

// private data member
T* ptr_;
Aux *counter_;

};

AhSeng Fan
  • 397
  • 5
  • 11

1 Answers1

2

As ref_count_ is a dependent name, you should use

this->ref_count_

or

Aux::ref_count_
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Does it depend on the template arguments for `AuxCounter`? How? I'm aware of [this](http://stackoverflow.com/a/993385/3552770), but this is different. Please, explain. – LogicStuff Nov 12 '15 at 20:27
  • Actually I'm confused too. Commonly it is no necessary to put this or scope operator in order to access member derived from base class. But why does it have to in this case? – AhSeng Fan Nov 12 '15 at 20:45
  • 1
    @AhSengFan - The full name is `S_ptr::Aux`, so it is dependent on `T`. – Bo Persson Nov 12 '15 at 21:14