C++中关于指针的理解

    xiaoxiao2025-02-08  13

    一、指针  1. 指针的值是一个地址,通过间接寻址运算符*来区分地址与指针所指地址保存的值区分开。  一个变量的地址称为该变量的指针。  如果有一个变量是用来专门存放另一变量地址(即指针)的,则称它为指针变量。  要区分指针和指针变量!!!  *实际上是运算符重载(C++中提及),表示指向。  例如: int *p,i;  p = &i;  p的值是i的地址,*p的值为i的值。  指针的两个属性:内容和位置。  其中位置可以存储在另一个变量中,这样便成为了指向指针的指针。  a、指针变量的定义  基类型 *指针变量名;  可以这么说:指针变量名是指向基类型的指针变量。  所定义的指针变量是指向基类型的指针变量,或者说是指针变量只能存放基类型数据的地址。  要注意:不能用一个整数给一个指针变量赋初值。  b、引用指针变量  与指针变量有关的运算符:  &——取地址运算符  *——指针运算符,也称间接访问运算符  c、指针作为函数参数  最经典的例子是swap函数:

    <code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include <iostream></span> using namespace std; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main() { void swap( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p1</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p2</span> ); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*po1</span>,<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*po2</span>,a,b; cin >> a>>b; po1 = &a; po2 = &b; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( a < b ) swap( po1,po2 ); cout<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"max="</span><<a<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"min="</span><<b<<endl; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } void swap( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p1</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p2</span> ) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> temp; temp = <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p1</span>; <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p1</span> = <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p2</span>; <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p2</span> = temp; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

    在上例中,如果写成这样,就不对

    <code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> swap( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> y ) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> temp; temp = x; x = y; y = temp; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

    因为实参与形参值的传递是单项的值传递方式,只能从实参传向形参,形参的改变无法传给实参。  即调用函数时不会改变实参指针变量的值,但可以改变实参指针变量所指向变量的值。

    为了动态的分配和回收内存空间,需要用到new和delete函数。  new:从内存中获得存储对象所需要的内存空间。  例如:p = new int;  只是程序请求足够空间来存储一个整数,这部分内存的地址存储在p中,可以简洁的通过指针对p指向的内存赋值,也可以使用赋值语句q = p将存储在p中的地址付给另一个指针。  delete p;  与delete有关的两个问题:  (1)、悬挂引用问题  执行上述语句后所释放的内存空间的地址仍然在p中,但对程序而言,这个内存空间已经不存在了,这就是悬挂引用问题。  为了避免悬挂引用问题,必须将一个特定地址赋给指针,可以将空地址赋给指针。  eg : p = 0;  意思是p变为空或者p是空的。  (2)、内存泄露问题  eg: p = new int;  p = new int;  在上面两条语句执行后,第一个p所指单元变得不可访问,导致了内存泄露问题。  应该是:  p = new int;  delete p;  p = new int;

    二、指针与数组  在C++中,数组必须提前声明,但是数组大小是很难预测的,这个问题可以通过指针来解决。  例如:

    <code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>],*p; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> = a[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; i++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> +=a[i]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//就等同于</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> = *a,i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; i++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> +=*(a+i);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//表达式a+i就等于内存地址 a + i*sizeof(int)</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//就等同于</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> = *a,p =a + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;p <a + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; p++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> +=*p;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

    数组也可以动态声明:  p = new int [n];  分配了足够的空间来存储n个整数。  指针p也可以看成一个数组型变量,这样就可以使用数组符号。  例如:

    <code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> = p[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;i < n;i++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span>+=p[i]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//=</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> = *p,i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;i < n;i++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span>+=*(p+i); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//=</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> =*p,q = p+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;q < p + n; q++ ) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span>+=*q;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

    如果p指向的数组现在不需要了,就必须使用一下语句将其释放:  delete [] p;  上面[]代表p指向一个数组,此外delete只用于使用new赋值的指针。  注意:  字符串是十分重要的数组类型,与指针有紧密的联系。  要注意许多预定义的函数操作字符串都是假定字符串一空字符’\0’结尾的,在使用时要注意这个问题。  三、指针与复制构造函数  1. 这个部分我想说的主要是在C++中进行对象的复制时,如果没有写复制构造函数的情况。  首先,如果类中包含指针变量,且要对对象进行复制。

    <code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Node { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *name; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> age; Node(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *n=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { name = strdup(n); age = a; } }; Node node1(“roger”,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>),node2(node1); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//上面的node2(node1); 等同于 node2 = node1;</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strcpy</span>( node2.name,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wendy"</span> ); node2.age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<node1.name<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span><<node1.age<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span><<node2.name<<<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span><<node2.age; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//结果是 wendy 30 wendy 20</span> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

    这就是Node定义中没有提供复制构造函数Node ( const Node& )的结果。  当执行node2(node1)时,复制构造函数是必不可少的。  如果没有定义复制构造函数,编译器会自动生成一个,但是编译器生成的复制构造函数只是逐个对成员进行复制。  因为Node中的数据成员name是一个指针,所以编译器自动生成的复制构造函数将node1.name的字符串地址复制给node2,而不是复制字符串的内容,即node1.name和node2.name指向同一个字符串,在本例中为roger,在后面进行name的变化时,roger变为wendy,同时node1.name和node2.name同时变化。  造成了错误。  为了防止错误的产生,必须定义一个合适的复制构造函数。

    <code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Node</span>{</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *name; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> age; Node ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *n = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ) { name = strdup(n); age = a; } Node ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Node& n )<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//复制构造函数</span> { name = strdup( n.name ); age = n.age; } };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

    使用上述复制构造函数后,声明node2(node1)生成了另一个roger副本,即node2.name与node1.name不指向同一个字符串,而是内容相同的两个字符串,这样改变node1/2的任意name对另一个不会造成影响。  2.赋值运算符也会引起同样的问题  如果用户没有提供赋值运算符的定义,下面的赋值操作  node1 = node2;  就会逐个对成员进行复制,引起上面的问题,解决方法是重载赋值运算符:

    <code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Node& <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">operator</span>= (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Node& n) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span> != &n ) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//no assignment to itself</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( name != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ) freee(name); name = strdup( n.name ); age = n.age; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//this指针指向对象本身</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

    四、指针与析构函数  这部分我想讲的是含有指针数据成员的Node类型的局部对象会发生什么。  局部对象在定义它们的区域之外是无效的,会被销毁,所占用内存也将被释放。  但如果对象数据成员中含有指向字符串的指针,即指针数据成员占用的内存将被释放,而字符串占用的内存却没有释放。  在对象销毁之后,以前可以通过指针访问的字符串不能访问了,(如果没有把字符串赋给其他变量的话),则字符串所占的内存再也无法释放,从而导致内存泄露。  只要是对象具有指向动态分配空间的数据成员,都存在这个问题。  为了解决这个问题,类定义中应该包含析构函数的定义。  当销毁对象,程序从定义对象的块中退出或调用delete时,析构函数抖动调用。  析构函数不带参数,也没有返回值,所以每个类中只能有一个析构函数。  对于上面的类Node。可以定一下面的析构函数:

    <code class="hljs applescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">~Node (){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( <span class="hljs-property" style="box-sizing: border-box;">name</span> != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> ) free( <span class="hljs-property" style="box-sizing: border-box;">name</span> ); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

    五、指针与引用变量  六、函数指针

    <code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> f( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> x ) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>*x; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sum</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> (*f) (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span>),<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n ,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> m ) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">double</span> result = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i =n; i <= m; i++ ) result += f(i); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

    其中double (*f) (double);  意味着f是一个指向函数的指针,该函数带有一个double参数,返回一个double值。  但是必须带()  例如: double *f(double);  指的是声明的函数返回一个指向double的指针。

    转载请注明原文地址: https://ju.6miu.com/read-1296209.html
    最新回复(0)