Xiangism

从一个无知角落里开始,蹒跚学步,一个未知到另一个未知,在跌跌撞撞中越走越快,越走越远,最后宇宙也为之开源。对于探索者来说,最后他们的思想总是变得和自己的足迹一样伟大。
随笔 - 62, 文章 - 1, 评论 - 220, 阅读 - 20万
  博客园  :: 首页  :: 联系 :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

C++指针系列

Posted on   Xiangism  阅读(729)  评论(0编辑  收藏  举报

写这篇文章总结C++指针的用法。

在C++中最好不要用new/delete来使用指针,而应该用智能指针来管理资源,智能指针就属boost做得最好了。boost的源码和使用方法在网上随便一搜就可以找到,在此就不哆嗦了。下面进入正文——

最后的指针

1. delete , delete[]的区别

  虽然要放弃new/delete的用法,但在这里还是要讲一个值得注意的地方。

  int* arr=new int[3]; //不同于new int(3),用[]是指明arr是具有3项的数组,而()是给申明一个整数,其初值为3

  在这总情况下,下面两种delete都正确

  delete arr; //OR   delete [] arr;

2. const不同位置的区别

 const int *p = new int(4); //或者 int const *p = new int(4);

这里用const后,就不能 *p = 5; 进行赋值。这时*p所指内容不能修改。

int *const p = new int(4);

不能用 p = NULL; 这里p本身不能被修改

3. 将指针作为参数时的注意事项

如果将一个指针传入函数,并且在这个函数中分配内存后再赋值,那么得用两维指针。如下

void GetValue(int *v)  //这个代码是错误的
{
    v = new int;
    *v = 100;  
}

 

void GetValue2(int **v) //应该用指针的指针
{
    *v = new int();
    **v = 100;
}

 

boost指针相关

一、boost基本指针 shared_ptr ,指向单个对象 

复制代码
//引入头文件和名字空间
#include
<boost/shared_ptr.hpp>
usingnamespace boost;

voidtry()
{
shared_ptr
<int> ptrInt(newint(1));//初值为1
ptrInt.get(); //获得数值1
……
//最后不需要用delete删除指针
}
复制代码

二、数组指针 shared_array

复制代码
#include <boost/shared_array.hpp>
usingnamespace boost;
voidtry()
{
shared_array
<Point> points(new Point[3]); //申明3个大小的数组,注意这里是[]
points[
0]=Point(10,20);
points[
1]=Point(30,20);
points[
2]=Point (30,50);
points.
get();//获得Point*类型的数据
}
复制代码

  而如果要将数组作为函数结果返回,则不能用下面的代码  

int* getArr()
{
shared_array
<int> arr(newint [10]);
……
return arr.get(); //错误
}

  而必然返回shared_array对象,  

shared_array<int>  GetArr()
{
shared_array
<int> arr(newint[10]);
arr[
0]=3;
arr[
9]=23;
return arr;
}

  而在接收这个返回值时也有需要注意的地方,下面这种获得方式是错误的

int main()
{
int*arr= GetArr().get(); //错误,必须得自定义一个变量存储函数的返回值
cout
<< arr[0]<<endl;
return0;
}

  应该用这种方式

int main()
{
shared_array
<int> t= GetArr();//
cout
<<t.get()[0]<<endl;
return0;
}

  

三、二维/多维数组指针

  先将如何用原始的C指针表示二维、多维数组 

复制代码
voidtry()
{
bool**m_sobel;
m_sobel
=newbool*[m_height]; //申明二维的高
for (int j=0;j<m_height;j++)
{
m_sobel[j]
=newbool[m_width]; //申明二维的宽
//如果想用memset对数组进行集中赋值,就只能在这里用下面的语句
memset(m_sobel[j],true,sizeof(true)*m_width;
}
//而不能在循环外,一次性赋值
// memset(m_sobel,true,sizeof(true)*m_width*m_height
//因为这时的二维数组在内存中不是连续的区域,因为是在循环中用new多次地申明内存,而不是一次性用new申明一大块内存

//用下面这个y,x的索引顺序获得或赋值对应位置的元素值
//x从左往右,y从上往下,原点在左上角
m_sobel[y][x]

//用下面这种方式对指针进行delete删除
for (int j=0;j<m_height;j++)
{
delete[] m_sobel[j];
}
delete[] m_sobel;
}
复制代码

  

  再介绍使用boost的multi_array类管理多维数组的指针

复制代码
#include <boost/multi_array.hpp>
vodi
try()
{
//2指明维数,extents中的参数指明每一维的大小
multi_array<int,2> arr(extents[width][height]);
for (int i=0;i<width;i++)
{
for (int j=0;j<height;j++)
{
//用这种次序对元素的值进行读取
arr[i][j]=i+j;
}
}
}
复制代码

  经过测试发现,在Debug模式下用boost管理多维数组比原生指针慢几十倍到几十倍,而在Release模式下经过优化后,则差别不会很大了。

 

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示
目录导航