C++中关于指针的理解

一、指针 
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>

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

  1. 为了动态的分配和回收内存空间,需要用到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的指针。

猜你喜欢

转载自blog.csdn.net/hnzziafyz/article/details/52201816
今日推荐