【问题标题】:template for a smartpointer and auto deletion of the pointer智能指针的模板和指针的自动删除
【发布时间】:2017-07-07 09:22:07
【问题描述】:

我在一个网站上遇到过这个简单的代码。我没有完全理解。如果有人可以逐行分解代码并解释,对我很有帮助。

这是用于创建智能指针模板的代码(自动删除指针是创建此类指针的主要座右铭)

#include <iostream>    
using namespace std;

template <class T>
class SmartPtr {
    T* ptr;

public:
    explicit SmartPtr(T* p = NULL) {
        ptr = p;
    }
    ~SmartPtr() {
        delete(ptr);
    }
    T& operator*() {
        return *ptr;
    }
    T* operator->() {
        return ptr;
    }
};

int main() {
    SmartPtr<int> ptr(new int());
    *ptr = 20;

    cout << *ptr;
    return 0;
}

【问题讨论】:

  • 我认为 SO 不是通用代码遍历的地方。但是,我认为这里有一个很好的演练:link
  • 只是模板类SmartPtr拥有T类型的指针。当它删除它会释放(删除)拥有的指针。 * 和 -> 运算符被重载,因此我们可以像直接使用拥有的指针一样使用它。

标签: c++ templates pointers smart-pointers


【解决方案1】:

您的类SmartPtr 封装了T 类型的指针,并重载了成员访问取消引用运算符 以允许访问封装的指针。此外,它在调用其析构函数时释放封装指针指向的分配内存。

你的课有评论:

template <class T>
class SmartPtr {
    T* ptr; // encapsulated pointer of type T

public:
    // constructor for SmartPtr class which assigns the specified pointer to the
    // encapsulated pointer
    explicit SmartPtr(T* p = NULL) {
        ptr = p;
    }
    // destructor for SmartPtr class which frees up the the allocated memory
    // pointed by the encapsulated pointer
    ~SmartPtr() {
        delete(ptr);
    }
    // overloads the dereference operator for SmartPtr class to allow syntax
    // like: *instance = value;
    T& operator*() {
        return *ptr;
    }
    // overloads the member access operator for SmartPtr class to allow syntax
    // like: instance->member();
    T* operator->() {
        return ptr;
    }
};

SmartPtr 类的用法显示在您提供的 main 函数中:

SmartPtr<int> ptr(new int());
*ptr = 20;

第一行执行class template instantiation 并通过调用构造函数以newly 创建的int 作为参数构造一个对象(ptr)。

第二行调用重载的解引用运算符并将值20 分配给封装的指针。这一行相当于:

ptr.operator*() = 20;

【讨论】:

  • 感谢您的回复。您已经很好地解释了驱动程序功能。作为一个初学者,我其实理解你的回复。
  • 不客气!随意将好的答案标记为有用并接受您认为回答了您的问题的答案。
【解决方案2】:

“逐行分解”有点过分了,以后尽量把个别不明白的部分提一下。但既然代码不多...

#include <iostream>
using namespace std;
template <class T> //make it a template in order to be able to store any type
class SmartPtr {
T *ptr; //wrapped pointer
public: explicit SmartPtr(T *p = NULL) { ptr = p; } //basic constructor

//delete pointer when the object dies.
//Note that this means that this is meant to be a unique pointer, 
//a shared pointer would have to count occurencies first
 ~SmartPtr() { delete(ptr); } 

//dereference operator to manipulate the content. 
//I prefer to go with T& instead of T & to make it clear that it is
//"reference of type T"
T & operator * () {  return *ptr; }
//bad operator which exposes the pointer itself.
//Make this const, like const T* operator -> () const { ... }
//else this could be used for the constructor again,
//leading to undefined behaviour when the pointer is deleted twice
T * operator -> () { return ptr; } }; //class ending brace at bad position

int main(){
SmartPtr<int> ptr(new int());
*ptr = 20;
cout << *ptr;
return 0; }

【讨论】:

  • 我不明白“这可以再次用于构造函数”这一点。请您详细说明一下。
  • @user1438832 您可以执行以下代码:SmartPtr&lt;int&gt; ptr(new int()); SmartPtr&lt;int&gt; ptr2(ptr.operator-&gt;());,这将创建两个对象,它们包含指向同一位置的指针。当两者都超出范围时,都将调用它们的析构函数,删除指针两次,这永远不会发生。顺便说一句,当你复制你的课程时也会发生同样的情况。喜欢SmartPtr&lt;int&gt; ptr2 = ptr;。出于这个原因,您应该遵守三法则并实现复制构造函数和赋值运算符。也许只是删除这两个。
  • @Aziuth 谢谢回复,我还是有点疑惑,这段代码在主函数SmartPtr&lt;int&gt; ptr(new int());987654324@里面做了什么
  • @ArvindSharma 它在堆上创建一个存储,并将指向该存储的指针传递给 SmartPtr 的构造函数,以包装它。在较小的步骤中:int* pointer_to_int = new int(); SmartPtr&lt;int&gt; smart_pointer_to_int(pointer_to_int);,尽管这显然直接暴露了应该被包装的指针。
  • @ArvindSharma 问题,您曾经使用过智能指针吗?因为这是基本的智能指针语法。如果您对此有疑问,请从有关如何使用 std::unique_ptr 和 std::shared_ptr 的教程开始。如果您在不知道应该如何使用它们的情况下尝试模仿它们,那是没有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多