我正在尝试使用我理解的模板在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
答案 0 :(得分:1)
您可以将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,我建议您不要硬编码T*
。而是在您的班级中添加以下类型别名,并相应地更改c。#。
using ptr_type = std::conditional_t<std::is_array<T>::value, std::decayt_t<T>, std::add_pointer_t<T>>;
smartPointer(ptr_type init)