C++智能指针

发布时间:2024年01月10日

目录

对构造函数的理解

对重载运算符的理解

智能指针的作用


智能指针是C++中一种特殊的指针,它能够自动管理内存,防止内存泄漏和悬挂指针等问题。智能指针的实现依赖于C++的RAII(资源获取即初始化)技术,即在对象的构造和析构过程中分别进行资源的分配和释放。

智能指针在内部管理着一个指针,指向某个动态分配的内存块。当智能指针对象销毁时,它会自动释放所指向的内存块。因此,智能指针能够确保内存的正确释放,避免了内存泄漏和非法内存访问等问题。

先看一个例子

#include<iostream>
using namespace std;
//这是一个智能指针类的基本定义
template<class T>
class smartpointer{
    private:
        T *ptr; 
    public:
        //构造函数和析构函数
        smartpointer(T *_ptr):ptr(_ptr){}
        ~smartpointer(){
            if(ptr!=nullptr)
            {
                cout << "smartptr is deleted";
                    delete ptr;
                ptr=nullptr;
            }
        }
        //重载运算符 *和->
        T & operator *(){
            return *ptr;
        }
        T *operator ->(){
            return ptr;
        }  
};
int main() {
    int *p = new int(10);
    smartpointer<int> sp(p);
    cout << "Value: " << *sp << endl;
    cout << "Pointer: " << sp.operator ->() << endl;
    system("pause");
    return 0;
}
?

Value: 10

Pointer: 0x191820

请按任意键继续. . .

对构造函数的理解

这个构造函数的语法是?C++11?中引入的初始化列表语法,用于初始化类成员变量。

具体来说,smartpointer(T *_ptr)?是构造函数的声明,其中?T *_ptr?是参数列表,表示该构造函数接受一个指向类型为?T?的指针作为参数。

冒号?:?表示接下来是构造函数的实现部分。

ptr(_ptr)?是一个成员函数调用表达式,它调用了名为?ptr?的成员函数,并将参数?_ptr?传递给它。这种写法通常用于初始化成员变量。

空的大括号?{}?表示构造函数的实现部分为空,即没有执行任何操作。

因此,整个构造函数的作用是接受一个指向类型为?T?的指针作为参数,并将其传递给名为?ptr?的成员函数进行处理,最终将处理结果存储在成员变量?ptr?中。

对重载运算符的理解

operator *()?重载了乘法运算符?*,使得使用?*ptr?时会调用该函数。函数返回的是指针?ptr?所指向的对象的引用,即?*ptr。

operator ->()?重载了箭头运算符?->,使得使用?ptr->?时会调用该函数。函数返回的是指针?ptr?本身,即?ptr。

智能指针的作用

自动管理内存:智能指针可以自动跟踪其所指向的内存块,并在对象的生命周期结束时自动释放内存。这样可以避免因程序员忘记释放内存而导致内存泄漏的问题。

防止悬挂指针:当一个指针指向的内存块被释放后,如果该指针仍然被使用,就会产生悬挂指针的问题。智能指针在析构时会自动将指针设置为nullptr,从而避免了悬挂指针的产生。

方便资源共享:对于多个指针指向同一个对象的场景,使用智能指针可以方便地实现资源共享,即当最后一个智能指针被销毁时,其所指向的对象才会被自动删除。这样可以避免多个指针分别管理同一个对象而导致的数据不一致问题。

简化代码:使用智能指针可以简化代码,减少内存管理相关的错误和异常。智能指针会自动处理内存的申请和释放,减少了程序员手动管理内存的负担。

提高性能:智能指针的实现通常基于引用计数技术,当一个对象被多个智能指针共享时,引用计数会增加。当一个智能指针离开作用域或被重新赋值时,引用计数会减少。只有当引用计数减少到0时,对象才会被真正删除。这种技术可以减少不必要的内存分配和释放操作,从而提高程序的性能。

#include<iostream>
#include <memory> // 添加头文件
using namespace std;
?
template<class T>
class test_class {
private:
    T a, b, c;
public:
    void p() {
        cout << a << b << c << endl;
    }
    test_class(T x) :a(x), b(3 + x), c(x - 3) {}
?
};
int main()
{
    auto_ptr<int> test1(new int(666));
    auto_ptr<test_class<int>> test2(new test_class<int>(6));
?
    cout << *test1 << endl;
    //test2实际上是智能指针auto_ptr类,p并不是它的成员函数,但是却可以调用p,说明其达到了指针的效果
    test2 -> p();
    system("pause");
    return 0;
}
?

输出结果:

666

693

请按任意键继续. . .

文章来源:https://blog.csdn.net/T20151470/article/details/135510374
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。