您的位置:首页 > 编程语言 > C语言/C++

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

2015-11-12 11:17 120 查看

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 的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: