使用模板在C 中的SmartPointer

SmartPointer in C++ using template

本文关键字:中的 SmartPointer      更新时间:2023-10-16

我正在尝试使用模板在C 中实现一个智能指针(基本上是唯一的指针),以了解我的理解。

这是我编码的

using namespace std;
template<typename T>
class smartPointer
{
    private:
        T *mPtr;
    public:
        smartPointer(T* init=nullptr):mPtr(init)
        {
            cout<<"Inside ctr"<<endl;
        }

        //silence the default ctr
        smartPointer() = delete;
        //disable copy ctr and copy assignment
        smartPointer  (const smartPointer& other) = delete;
        smartPointer& operator=(const smartPointer& other) = delete;
        //implement move ctr and move assignment
        smartPointer  (smartPointer&& other)
        {
            cout<<"Inside move ctr "<<endl;
            mPtr = other.mPtr;
            other.mPtr = nullptr;
        }
        smartPointer& operator=(smartPointer&& other)
        {
            cout<<"Inside move = before "<<endl;
            if(&other != this)
            {
                mPtr = other.mPtr;
                other.mPtr = nullptr;
                cout<<"Inside move = after "<<endl;
            }
        return *this;
        }
        //deference
        T& operator*()
        {
            return *mPtr;
        }
        //arrow  access operator
        T* operator->()
        {   
            return mPtr;
        }
        ~smartPointer()
        {   
            cout<<"Inside ~dtr"<<endl;
            if(mPtr != nullptr)
            delete mPtr;
        }
};

int main()
{
     smartPointer<int> sptr(new int);
     // Even smartPointer<int> sptr(new int[20]); too works
     *sptr = 10;
     cout<<"Value pointed by the pointer  is "<<*sptr<<endl;     
    smartPointer<int> sptr2(new int);
//  sptr2 = sptr; // complains as expected
    sptr2 = move(sptr); // works well
    /*
    How to 
    smartPointer<int[]>  sptr(new int[20]); 
    */
    return 0;
}

如何使此智能指针用于SmartPointer?

我给出的构建命令是G -STD = C 11 -SMARTPOINTER.CPP -O SMARTPOINTER

您可以将operator[]添加到基本模板中,并使用SFINAE确保仅在类型为数组类型时进行编译。您将做同样的事情以确保仅针对非阵列版本编译operaotr*operaotr->。然后,标签调度可用于调用正确的delete表达式。

template<typename T>
class smartPointer
{
    private:
        T *mPtr;
        del_member(std::true_type) { delete[] mPtr; }
        del_member(std::false_type) { delete mPtr; }
    public:
        // Removed you code for brevity.
        //deference
        auto operator*() -> std::enable_if_t<!std::is_array<T>::value, T&>
        {
            return *mPtr;
        }
        //arrow  access operator
        auto operator->() -> std::enable_if_t<!std::is_array<T>::value, T*>
        {   
            return mPtr;
        }
        auto operator[](std::size_t idx) -> std::enable_if_t<std::is_array<T>::value, T&>
        {   
            return mPtr[idx];
        }
        ~smartPointer()
        {   
            del_member(std::is_array<T>{});
        }
};

以上是完全合法的,并且可以存在于相同的模板中。请记住,仅在使用时才实例化模板成员。因此,除非您的班级用户尝试使用 基础指针不应支持的操作员,否则他们不会遇到任何错误。


如果您的编译器不支持C 14类型特征,则可以将上述返回类型转到表格:

typename std::enable_if<CONDITION, TYPE>::type

对于您的c'tor,我建议您不要硬代码T*。相反

using ptr_type = std::conditional_t<std::is_array<T>::value, std::decayt_t<T>, std::add_pointer_t<T>>;
smartPointer(ptr_type init)