赋值运算符函数的注意事项 ,指针和多维数组的讨论 (c/c++)

1.赋值运算符函数

String & String::operator = (String & str)
{
if(this == &str)
return *this;
delete[]m_pdata;
m_pdata = null;
m_pdata = new char[strlen(str.m_pdata)+1];
strcpy(m_pdata,str.m_pdata);
return *this;
}

1,返回值类型为该类型的引用

原因:只有返回引用,才能进行连续赋值,如果返回void,应用该赋值运算符,不能进行连续赋值
str1 = str2 = str3

2,传入的参数类型声明为常量引用

原因:如果传入的参数为实例而不是引用,从形参赋值给实参,将调用复制构造函数。参数为引用就避免这种消耗,提高效率。为了不改变传入的实例,加const。

3,释放实例自身的内存

在分配新内存之前,要释放自身已有的空间,否则将出现内存泄露。

4,自我赋值安全

判断传入的参数和当前实例(*this)是不是同一个实例。若为同一个,一旦释放了自身的内存,传入的参数的内存也要被释放。
if(this== &str)
return *this;

5,异常安全性

上面的代码,在分配内存之前释放m_pdata的内存,如果new char 出现异常,m_pdata将为成为一个空指针,这样的指针危害性很大。解决办法就是先创建一个临时实例。
char * temp = m_pdata;
m_pdata = new char (strlen(str.m_pdata) +1);
delete temp;
return *this;
异常安全性往往自动获得自我赋值安全性

2.指针和多维数组

int zippo[4][2]; 二维数组(含4个包含两个Int的数组的数组)

1.zippo :

数组名,其值是zippo首元素(两个整数值)的地址,而zippo的首元素在这里为一个包含两个int的数组。

2.zippo[0]:

包含两个int值的数组(zippo的首元素),其值也为首元素(一个整数值)地址,一个整数和含两个int的数组开始于同一个地址,所以zippo = zippo[0](值相等)。

3.zippo和zippo[0]区别:

但是,当进行指针运算时,zippo所指的对象大小是两个int,而zippo[0]所指为一个int,zippo+1 和zippo[0]+1 结果不同

4.zippo[0][0] :

首元素(一个整数值),所以zippo[0] = & zippo[0][0]。

5.*zippo,*zippo[0]

*zippo 代表首元素zippo[0]的值,zippo[0]值为&zippo[0][0]。所以*zippo = &zippo[0][0] ,两边同时再取地址,**zippo = zippo[0][0]。zippo为地址的地址。
*zippo[0]代表zippo[0][0]的值。

6.分析* ( *(zippo+2)+1)

zippo+2 :第三个(包含两个int的数组)的地址。
*(zippo+2):第三个(包含两个int的数组),实际为第三排第一个元素的地址。
*(zippo+2)+1:第三个包含两个int的数组的第二个元素地址。
* (*(zippo+2)+1):数组第三行第二个元素的值(zippo[2][1])

7.指向多维数组的指针

这个最近也是吃过一次亏,好久没用了,突然用的时候,声明指向二维数组的指针,直接来了一个int** ptr,还自我感觉良好,调试的时候就傻逼了,这个确实是个容易犯错的地方。
声明指向zippo的指针变量ptr。上面第一条已经说过,zippo是首元素(两个int)的地址。所以ptr也要指向含两个int的数组。
int(*ptr)[2] //ptr指向含两个int的数组的指针。
顺便我们再解释下:
int *ptr[2],因为[]的优先级比较高,所以ptr就成了包含两个指向int的指针的数组。
在声明以二维数组为参数的函数时
void function(int (*ptr)[2]);
void function(int ptr[][2]); //第一个空的方括号表明ptr是一个指针

8.指针之间的赋值规则

要类型相同,无类型强制转换
int * pt;
int (* pa)[3];
int ar1[2][3];
int ar2[3][2];
int **p2; //指向指针的指针

pt = &ar1[0][0] ; //都指向int
pt = ar1[0] ; //都指向int
pt = ar1; //ar1指向3个int值构成的数组,pt指向int
pa = ar1 ; //都指向int[3]
p2 = ar2; //p2指向int的指针,ar2指向2个int构成的数组
*p2 = ar2[0] ; //都是指向int
p2 = * pt; //都是指向int*

int * p1;
const int * p2;
const int ** pp2;

p1 = p2 ; //非法,不能把const指针赋给非const
p2 = p1; //合法
pp2 = & p1; //非法,非const 赋给const,只能进行一层间接运算
在进行两层间接运算时,赋值不再安全
const int **pp2;
int * p1;
const int n = 13;
pp2 = & p1;
*pp2 = &n;
*p1 = 10; //将改变const n 的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值