c__problem

本文详细介绍了C++中指针的初始化方法及其重要性,包括如何避免野指针的产生,指针与内存之间的关系,以及如何正确地使用指针进行内存管理。此外,还探讨了复制构造函数的概念及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、const的作用有两点:
  1. 限制对象的成员函数改变对象的数据成员,保护了程序的健壮性和稳定性;
  2. 如果该成员函数试图去修改对象的数据成员时,编译器就会提示错误,从而达到帮助我们寻找错误的目的。

2、指针

    1、指针变量进行初始化,以防止它变成“野指针”。因为一个野指针可以指向任何内存地址,并且可以对该地址中的数值进行随意地修改或删除,这样很可能对整个程序造成不良后果!所以在定义指针的时候,一定要先将其初始化成0,即上面函数中的“int *p=0”。这样就会把这个指针的值限定成为0,从指针中的概念而不会引发野指针的问题。

    2、在这里分析一下造成这种原因的机理。(注:在这里的矩形分别代表了整型变量i和指针变量p。矩形框中间的大矩形代表了该变量的数值,而小矩形代表了该变量的地址。)我们可以看到,如蓝色的笔所示,i的地址为A,p的地址为B。现在有绿色的笔标出了程序第13行中的语句,将i的地址赋给p,那么如右图所示,p里面的值就成为了i的地址A。在看看红笔。我们采用了间接运算符*访问i的值。正如红线所标示的一样,首先,它从p的值中找到i的地址为A,然后在从i的地址中读取到i的值为3。这样,就完成了利用指针p读取整型变量i的值了。

  3、只要*p修改了i的值,那么连i自己也会把自己的值从3修改到了5。

  4、我们需要向指针p说明变量i的地址(p=&i),之后我们才能对其进行操作(*p=5)。这里绝对不可能是先操作了再找地址,这肯定是不符合逻辑的。如果程序这样写,在编译的时候不会犯错,但是运行的时候错误就出来了,如下:

2

 

3、8个0是因为在32位系统中0x00000000中0x表示16进制,00000000每个0占4位一共32位

 

4、  好了,从上面我们就可以看到,其实,想要对指针进行初始化,也有三种方法:

  1. 利用int *p=0;这个语句老老实实的将指针初始化了;
  2. 把int *p=0和p=&i这两句话连成一句话: int *p=&i;这样,就既把指针变量p初始化了,又把它指向了某个值;
  3. 如果非要用常量来初始化一个指针。那么就只有利用强制类型转换,找一个内存地址,利用(ElementType *) 来把常量转换成内存中的一个地址。既采用:
ElementType *p=(ElementType *)[常量]

 5、

我们在程序的第16行和第24行分别采用了堆分配(new Human)和栈分配(Human unqiue)的方式来创建了两个对象。我们从输出可以清楚的看出来,只有在利用栈分配对象的时候,编译器在最后才会自动调用该类的析构函数来销毁这个对象;而对于利用堆分配的方式,编译器是不会自动释放其所占的内存的。只有通过程序员自己在最后调用delete来释放该内存区域。即,如果我们在上面程序的第20行上面加上

?
delete tom;

 那么编译器才会调用析构函数来释放对象tom所占用的内存空间。结果如下图所示:

综上所述:

  1. 如果我们采用来定义对象。那么该对象会由系统自动为其在栈中间开辟空间,然后在释放对象的时候,比如说运行到右大括号的时候,系统也会自动的调用析构函数释放该对象所占用的内存空间。
  2. 如果我们采用来定义对象。即利用new的方式来分配空间给需要的对象,那么我们就必须要自行释放其所占用的内存,否则该对象所占用的内存会在整个程序全部结束的时候才会被操作系统回收。

    3、我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身。

在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL),这样做可以有效的杜绝野指针情况的发生。

   对于NULL的应用,我们不应该仅限于上面的方法,还可以应用NULL来判断指针是否初始化成功了,如下例if中的判断方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
  
int main()
{
     int *p= new int ;
     if (p==NULL)
     {
         //判断指针p是不是空指针,如果是空指针,那么程序在这里就应该报错
         //报错的方法有很多,比如说返回一个ERROR值:
         //return ERROR;
     }
  
     //判断了操作成功之后我们才能进行一系列的操作
     //...
  
     //用完指针p之后,一定要将其删掉。这样可以杜绝野指针的存在
     delete p;
     //删除指针p之后,一定要加上下面这句话,免得成为野指针
     p=NULL;
}

         好了,下次一定要记住,在分配空间给指针之后,一定要用NULL来判断一下是否成功了。然后在删除这个指针的时候,也要用NULL来赋给指针,杜绝成为野指针!

6、

      复制构造函数利用下面这行语句来复制一个对象

?
A (A &a)

      从上面这句话可以看出,所有的复制构造函数均只有一个参数,及对同一个类的对象的引用。这句话的意思其实就是,如果我们在程序中写上下面这样一句话:

?
A b=(a)

      或者是:

?
A b(a)

      就表示b其实是对象a的一个拷贝。说穿了,b就是a,a就是b。

 7、迷途指针

 

8、友元函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值