c++ 基础知识(一) 指针

本文详细介绍了C++中的指针,包括指针的基本概念,如指针类型、所指向的类型、指针值和内存区。深入探讨了智能指针,如已废弃的`auto_ptr`及其问题,以及更安全的`std::unique_ptr`和`std::shared_ptr`的使用。同时提到了函数指针和指针函数,并总结了使用指针时的注意事项,帮助读者理解并避免指针陷阱。
摘要由CSDN通过智能技术生成

 

目录

一、指针的基本概念

二、智能指针

   1、auto_ptr:

三、函数指针与指针函数

四、指针的注意事项

 


一、指针的基本概念

指针是一个特殊的变量,它里面存放的值为一个内存中的一个地址。要搞清楚指针,需要知道四个方面:指针的类型,指针所指向的类型,指针的值和指针所指向的内存区。

举例说明:

1、int *ptr;  

2、char *ptr;  

以上两个指针声明:

指针的类型:

       1的指针类型为int*。

        2的指针类型为char*。

指针所指向的类型:

       1所指向的类型为int。

        2所指向的类型为char。

指针的值:

    指针的值是指指针本身存储的数值,这个值被编译器当做一个地址,而不是一个一般的值。

指针所指向的内存区:

     从指针的值开始,到sizeof(指针所指向的类型)这块内存区。

空指针:是指向NULL的指针,没有指任何内存地址。

野指针:指向了一块内存地址,但是这块地址不存在。

二、智能指针

  那什么是智能指针呢?

   智能指针本质上是用来存储指向动态分配对象指针的类,该指针来确保程序不存在内存泄漏且是异常安全的。我们下面一点点开始讲解:

   1、auto_ptr:

         虽然这个auto_ptr已经废弃了,但是我们还是来聊聊它的思想和不足之处。

#include <memory>

int main()
{
    //初始化方式1
    std::auto_ptr<int> sp1(new int(8));
    //初始化方式2
    std::auto_ptr<int> sp2;
    sp2.reset(new int(8));

    return 0;
}

     如上图代码,sp1和sp2均持有一个在堆上分配int对象的类,这两块内存分别可以在sp1,sp2释放时自动释放。auto_ptr让人容易误用的是其不常用的复制语句。即当复制(拷贝复制或者operator=复制)一个auto_ptr对象时,原对象所持有的堆内存对象会转移到新的对象中,

      举例:

std::auto_ptr<int> sp1(new int(8));
	std::auto_ptr<int> sp2(sp1);
	if (sp1.get() != NULL)
	{
		std::cout << "sp1 is not empty." << std::endl;
	}
	else
	{
		std::cout << "sp1 is empty." << std::endl;
	}

	if (sp2.get() != NULL)
	{
		std::cout << "sp2 is not empty." << std::endl;
	}
	else
	{
		std::cout << "sp2 is empty." << std::endl;
	}
	//测试赋值构造
	std::auto_ptr<int> sp3(new int(8));
	std::auto_ptr<int> sp4;
	sp4 = sp3;
	if (sp3.get() != NULL)
	{
		std::cout << "sp3 is not empty." << std::endl;
	}
	else
	{
		std::cout << "sp3 is empty." << std::endl;
	}

	if (sp4.get() != NULL)
	{
		std::cout << "sp4 is not empty." << std::endl;
	}
	else
	{
		std::cout << "sp4 is empty." << std::endl;
	}

运行代码可以得出:

     

所以这个会发生意想不到的错误。基于这个缺陷,后来又引用了其他三种智能指针: std::unique_ptr,std::shared_ptr,std::weak_ptr。

2、std::unique_ptr

它对其所拥有的堆内存具有唯一拥有权,也就是说它的引用计数永远为1,它销毁时,会释放其所拥有的堆内存。可以使用以下进行初始化:

//初始化方式1
std::unique_ptr<int>  sp1(new int(123));
//初始化方式2
std::unique_ptr<int> sp2;
sp2.reset(new int(123));
//初始化方式3
std::unique_ptr<int> sp3=std::make_unique<int>(123):

 使用初始化方式3比较好。

unique_ptr是将拷贝构造函数和复制构造函数标志为delete,防止复制语句,避免和auto_ptr一样。

那么此时unique_ptr是无法复制,那么如何将 里面的堆内存转移出去给另一个unique_str对象。是通过move移动的。

#include <memory>

int main()
{
    std::unique_ptr<int> sp1(std::make_unique<int>(123));

    std::unique_ptr<int> sp2(std::move(sp1));

    std::unique_ptr<int> sp3;
    sp3 = std::move(sp2);

    return 0;
}

通过move后,以上代码执行完成后,sp1和sp2变成了一个空的智能指针对象,

3、std::shared_ptr

         std::unique_ptr持有的对象具有独占性,但是std::shared_ptr持有的资源可以在多个shared_ptr进行共享,每多一个shared_ptr对资源的引用,则引用计数就加1。每一个指向shared_ptr对象析构时,则引用计数则减一,最后一个shared_ptr对象析构时,则发现资源计数为0,则释放其持有的资源。

三、函数指针与指针函数

四、指针的注意事项

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值