﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-AlexusLi-最新评论</title><link>http://www.cnblogs.com/alexusli/CommentsRSS.aspx</link><description /><language>zh-cn</language><pubDate>Sat, 17 Oct 2009 14:48:05 GMT</pubDate><lastBuildDate>Sat, 17 Oct 2009 14:48:05 GMT</lastBuildDate><generator>cnblogs</generator><item><title>Re:Visitor模式</title><link>http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663996</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Thu, 01 Oct 2009 20:39:30 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663996</guid><description><![CDATA[任何问题都可以通过增加间接层次的方法解决。<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-10-02 04:39 <a href="http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663996#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:Visitor模式</title><link>http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663995</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Thu, 01 Oct 2009 20:27:13 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663995</guid><description><![CDATA[我想在一个类层次(class   hierarchy)中增加一个新的虚函数，但是这个类层次是由另外一帮人维护的，其他人碰都不能碰：
  class   Personnel  
  {  
  public:  
      virtual   void   Pay   (   /*...*/   )   =   0;  
      virtual   void   Promote(   /*...*/   )   =   0;  
      virtual   void   Accept   (   PersonnelV&amp;   )   =   0;  
      //   ...   other   functions   ...  
  };
  class   Officer   :   public   Personnel   {   /*   override   virtuals   */   };  
  class   Captain   :   public   Officer   {   /*   override   virtuals   */   };  
  class   First   :   public   Officer   {   /*   override   virtuals   */   };  
  我想要一个函数，如果对象是船长(Captain)就这么做，如果是大副(First   Officer)就那么做。Virtual   function正是解决之道，在Personnel或者Officer中声明它，而在Captain和First覆盖(override)它。     
  糟糕的是，我不能增加这么一个虚函数。我知道可以用RTTI给出一个解决方案：      
  void   f(   Officer   &amp;o   )  
  {  
      if(   dynamic_cast&lt;Captain*&gt;(&amp;o)   )  
          /*   do   one   thing   */  
      else   if(   dynamic_cast&lt;First*&gt;(&amp;o)   )  
          /*   do   another   thing   */  
  }   
  int   main()  
  {  
      Captain   k;  
      First   s;  
      f(   k   );  
      f(   s   );  
  }    
  /*   A   not-atypical   C   program   */  
  void   f(struct   someStruct   *s)  
  {  
      switch(s-&gt;type)   {  
      case   APPLE:  
          /*   do   one   thing   */  
          break;  
      case   ORANGE:  
          /*   do   another   thing   */  
          break;  
      /*   ...   etc.   ...   */  
      }  
  }    
   
  “很好，小菜鸟。C语言门徒通常老习惯改不掉。但是，你应该知道，通过使用virtual   function，你增加了一个间接层次。”她放下笔，“你所需要的不就是一个新的虚函数吗？”    
   
  “是的。可是我没有权力这么干。”    
   
  “因为你无权修改类层次，对吧！”    
   
  “您终于了解了情况，我们没法动它。也不知道这个该死的类层次是哪个家伙设计的...”   我嘀嘀咕咕着。    
   
  “是我设计的。”    
   
  “啊...，真的？！这个，嘿嘿...”，我极为尴尬。    
   
  “这个类层次必须非常稳定，因为有跨平台的问题。但是它的设计允许你增加新的virtual   function，而不必烦劳RTTI。你可以通过增加一个间接层次的办法解决这个问题。请问，Personnel::Accept是什么?”    
   
  ”嗯，这个...”    
   
  “这个类实现了一个模式，可惜这个模式的名字起得不太好，是个PNP，叫Visitor模式。”    
   
  [译者注：PNP，Poor-Named   Pattern,   没起好名字的模式]    
   
  “啊，我刚刚读过Visitor模式。但是那只不过是允许若干对象之间相互迭代访问的模式，不是吗？”    
   
  她叹了一口气，“这是流行的错误理解。那个V，我觉得毋宁说是Visitor，还不如说是Virtual更好。这个PNP最重要的用途是允许在不改变类层次的前提下，向已经存在的类层次中增加新的虚函数。首先来看看Personnel及其派生类的Accept实现细节。”她拿起笔写下：    
   
  void   Personnel::Accept(   PersonnelV&amp;   v   )  
      {   v.Visit(   *this   );   }  
   
  void   Officer::Accept   (   PersonnelV&amp;   v   )  
      {   v.Visit(   *this   );   }  
   
  void   Captain::Accept   (   PersonnelV&amp;   v   )  
      {   v.Visit(   *this   );   }  
   
  void   First::Accept   (   PersonnelV&amp;   v   )  
      {   v.Visit(   *this   );   }  
   
  “Visitor的基类如下：”    
   
  class   PersonnelV/*isitor*/  
  {  
  public:  
      virtual   void   Visit(   Personnel&amp;   )   =   0;  
      virtual   void   Visit(   Officer&amp;   )   =   0;  
      virtual   void   Visit(   Captain&amp;   )   =   0;  
      virtual   void   Visit(   First&amp;   )   =   0;  
  };  
   
  “啊，我记起来了。当我要利用Personnel类层次的多态性时，我只要调用Personnel::Accept(myVisitorObject)。由于Accept是虚函数，我的myVisitorObject.Visit()会针对正确的对象类型调用，根据重载法则，编译器会挑选最贴切的那个 Visit来调用。这不相当于增加了一个新的虚拟函数了吗？”    
   
  “没错，小菜鸟。只要类层次支持Accept，我们就可以在不改动类层次的情况下增加新的虚函数了。”    
   
  “好了，我现在知道该怎么办了”，我写道：    
   
  class   DoSomething   :   public   PersonnelV  
  {  
  public:  
      virtual   void   Visit(   Personnel&amp;   );  
      virtual   void   Visit(   Officer&amp;   );  
      virtual   void   Visit(   Captain&amp;   );  
      virtual   void   Visit(   First&amp;   );  
  };  
   
  void   DoSomething::Visit(   Captain&amp;   c   )  
  {  
      if(   femaleGuestStarIsPresent   )  
          c.TurnOnCharm();  
      else  
          c.StartFight();  
  }  
   
  void   DoSomething::Visit(   First&amp;   f   )  
  {  
      f.RaiseEyebrowAtCaptainsBehavior();  
  }  
  void   f(   Personnel&amp;   p   )  
  {  
      p.Accept(   DoSomething()   );   //   相当于   p.DoSomething()  
  }  
   
  int   main()  
  {  
      Captain   k;  
      First   s;  
   
      f(   k   );  
      f(   s   );  
  }    
    from:http://topic.csdn.net/t/20051231/14/4492965.html<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-10-02 04:27 <a href="http://www.cnblogs.com/alexusli/archive/2009/10/02/1577328.html#1663995#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:Template Method模板方法模式</title><link>http://www.cnblogs.com/alexusli/archive/2009/10/01/1576580.html#1663100</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Wed, 30 Sep 2009 18:35:12 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/10/01/1576580.html#1663100</guid><description><![CDATA[今天开始学习设计模式中的第三个类型——行为型模式。

行为模式：

行为型模式涉及到算法和对象间职责的分配。将注意力从控制流转移到对象间的联系方式上来。

       行为模式分为：行为类模式和行为对象模式。行为类模式使用继承机制在类间分派行为；行为对象模式使用对象复合而不是继承。

Template Method模板方法模式

       Template Method模板方法模式介绍：

       Template Method模板方法模式是一种行为型模式，具体点说是行为类型模式。主要解决在软件构建过程中，对于某一项任务，常常有稳定的整体操作结构，但各个子步骤却有很多改变的需求，或者由于固有的原因而无法和任务的整体结构同时实现。

       GoF《设计模式》中说道：定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

       Template Method模式的结构


       定义场景

       单看结构不好理解，我们来结合程序进行分析。现在定义一个场景：我想大家都玩过极品飞车（我相当喜欢）。游戏中有很多的汽车，但是从操作角度看大同小异。无非是起步（StartUp）、行驶（Run）、停车（Stop）等等行为。汽车行驶的动作之间可能存在着差异，例如：手动档和自动档，但是接口是一样的，换句话说，基本都是这几个动作。结合Template Method模式讲就是在这个程序中，结构（对汽车的操作）是稳定的，但是变化在于各个子步骤（操作行为的具体实现）。

       程序实现与结构分析

       首先我们需要一个汽车的抽象类（结构图中的AbstractClass）

       public abstract class AbstractCar

    {

        protected abstract string StartUp();

        protected abstract string Run();

        protected abstract string Stop();

 

        public void DriveOnTheRoad()

        {

            Console.WriteLine(StartUp());

            Console.WriteLine(Run());

            Console.WriteLine(Stop());

        }

}

在这段代码中，抽象方法StartUp、Run、Stop叫做primitive operation（原语操作），它们是在子类中的扩展点，例如我们要编写一辆BORA的实现，在他继承AbstractCar后，可以在这几个primitive operation上进行自己个步骤的实现。

AbstractCar中的DriveOnTheRoad方法叫做template method（模板方法），template method用primitive operation定义一个算法，是相对稳定的部分。（子类中重新定义primitive operation）。

    然后我们要实现一辆BORA汽车（结构图中的ConcreteClass）

    public class BORA : AbstractCar

    {

        protected override string StartUp()

        {

            return &quot;BORA is StartUp&quot;;

        }

 

        protected override string Run()

        {

            return &quot;BORA is Running&quot;;

        }

 

        protected override string Stop()

        {

            return &quot;BORA is Stoped&quot;;

        }

}

接下来我们进行客户程序的实现

class Program

    {

        static void Main(string[] args)

        {

            ClientApp.Drive(new BORA());

            Console.Read();

        }

}

public class ClientApp

    {

        public static void Drive(AbstractCar car)

        {

            car.DriveOnTheRoad();

        }

}

运行结果如下：

BORA is StartUp

BORA is Running

BORA is Stoped

   

Template Method要点

1、  Template Method模式是一种非常基础性的设计模式，在面向对象系统中有着大量的应用。它用最简洁的机制（虚函数的多态性）为了很多应用程序框架提供了灵活的扩展点，是代码复用方面的基本实现结构。

2、  除了可以灵活应对子步骤的变化外，“Don't call me.Let me Call you”的反向控制结构是Template Method的典型应用。“Don’t call me.Let me Call you”是指一个父类调用一个子类的操作，而不是相反。

3、  在具体实现方面，被Template Method调用的虚方法可以具有实现，也可以没有任何实现（抽象方法、纯虚方法），但一般推荐将它们设置为protected方法。可以没有具体实现的方法应该称为hook operation（钩子操作），提供了缺省的行为，子类可以在必要时进行扩展。

4、  尽量减少primitive operation，因为需要重新定义的操作越多，客户程序就越长<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-10-01 02:35 <a href="http://www.cnblogs.com/alexusli/archive/2009/10/01/1576580.html#1663100#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:Template Method模板方法模式</title><link>http://www.cnblogs.com/alexusli/archive/2009/09/29/1576580.html#1661945</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Tue, 29 Sep 2009 11:59:52 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/09/29/1576580.html#1661945</guid><description><![CDATA[ 重构的原则

在对一个继承的等级结构做重构时，一个应当遵从的原则便是将行为尽量移动到结构的高端，而将状态尽量移动到结构的低端。

1995年，Auer曾在文献【AUER95】中指出：

   1. 应当根据行为而不是状态定义一个类。也就是说，一个类的实现首先建立在行为的基础之上，而不是建立在状态的基础之上。
   2. 在实现行为时，是用抽象状态而不是用具体状态。如果一个行为涉及到对象的状态时，使用间接的引用而不是直接的引用。换言之，应当使用取值方法而不是直接引用属性。
   3. 给操作划分层次。一个类的行为应当放到一个小组核心方法（Kernel Methods）里面，这些方法可以很方便地在子类中加以置换。
   4.  将状态属性的确认推迟到子类中。不要在抽象类中过早地声明属性变量，应将它们尽量地推迟到子类中去声明。在抽象超类中，如果需要状态属性的话，可以调用抽象的取值方法，而将抽象的取值方法的实现放到具体子类中。

如果能够遵从这样的原则，那么就可以在等级结构中将接口与实现分隔开来，将抽象与具体分割开来，从而保证代码可以最大限度地被复用。这个过程实际上是将设计师引导到模版方法模式上去。<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-09-29 19:59 <a href="http://www.cnblogs.com/alexusli/archive/2009/09/29/1576580.html#1661945#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:插入排序&amp;amp;&amp;amp;二分插入排序</title><link>http://www.cnblogs.com/alexusli/archive/2009/09/17/1568551.html#1650220</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Thu, 17 Sep 2009 09:52:21 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/09/17/1568551.html#1650220</guid><description><![CDATA[ShellSort


#include &quot;StdAfx.h&quot;
#include &quot;ShellSortClass.h&quot;

ShellSortClass::ShellSortClass(void)
{
}

ShellSortClass::~ShellSortClass(void)
{
}
void ShellSortClass::Shell_Sort_Ini(std::vector&lt;int&gt; _IntVector, int _Size)
{
	for(int i=0;i&lt;_Size;i++)
	{
		IntVector.push_back(_IntVector[i]);
	}
	VectorSize=_Size;
}
void ShellSortClass::Shell_Sort_RunSort()
{
	int SwapValue,j;
	int Gap=VectorSize/2;
	while(Gap)
	{

		for(int i=Gap;i&lt;VectorSize;i++)
		{
			j=i;
			SwapValue=IntVector[i];
			while(j&gt;=Gap&amp;&amp;SwapValue&lt;IntVector[j-Gap])
			{
				IntVector[j]=IntVector[j-Gap];
				j=j-Gap;
			}
			IntVector[j]=SwapValue;
		}
		Gap=Gap/2;
	}
}
void ShellSortClass::Shell_Sort_Output()
{
	for(int i=0;i&lt; IntVector.size();i++)
	{
		cout&lt;&lt;IntVector[i]&lt;&lt;&quot; &quot;;
		if(i&gt;5&amp;&amp;i%10==0)
			cout&lt;&lt;endl;
	}
	cout&lt;&lt;endl;
}
<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-09-17 17:52 <a href="http://www.cnblogs.com/alexusli/archive/2009/09/17/1568551.html#1650220#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:基于 TCP (面向连接)和无连接UDP协议的 socket 套接字编程</title><link>http://www.cnblogs.com/alexusli/archive/2009/09/16/1568050.html#1649046</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Wed, 16 Sep 2009 11:53:54 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/09/16/1568050.html#1649046</guid><description><![CDATA[http://hi.baidu.com/tjulxh/blog/item/cb89e8d556166806a08bb76b.html<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-09-16 19:53 <a href="http://www.cnblogs.com/alexusli/archive/2009/09/16/1568050.html#1649046#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:WinSock学习笔记（二）</title><link>http://www.cnblogs.com/alexusli/archive/2009/09/12/1565101.html#1644149</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Fri, 11 Sep 2009 20:16:24 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/09/12/1565101.html#1644149</guid><description><![CDATA[from:http://www.vckbase.com/document/viewdoc/?id=1036<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-09-12 04:16 <a href="http://www.cnblogs.com/alexusli/archive/2009/09/12/1565101.html#1644149#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Re:指针与引用的区别:指针与引用</title><link>http://www.cnblogs.com/alexusli/archive/2009/09/05/1561000.html#1637218</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Sat, 05 Sep 2009 12:40:26 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/09/05/1561000.html#1637218</guid><description><![CDATA[引用（reference）是c++的初学者比较容易迷惑的概念。下面我们比较详细地讨论引用。

一、引用的概念

引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似，只是用&amp;代替了*。
例如： Point pt1(10,10);
Point &amp;pt2=pt1; 定义了pt2为pt1的引用。通过这样的定义，pt1和pt2表示同一对象。
需要特别强调的是引用并不产生对象的副本，仅仅是对象的同义词。因此，当下面的语句执行后：
pt1.offset（2，2）；
pt1和pt2都具有（12，12）的值。
引用必须在定义时马上被初始化，因为它必须是某个东西的同义词。你不能先定义一个引用后才
初始化它。例如下面语句是非法的：
Point &amp;pt3；
pt3=pt1；
那么既然引用只是某个东西的同义词，它有什么用途呢？
下面讨论引用的两个主要用途：作为函数参数以及从函数中返回左值。

二、引用参数

1、传递可变参数
传统的c中，函数在调用时参数是通过值来传递的，这就是说函数的参数不具备返回值的能力。
所以在传统的c中，如果需要函数的参数具有返回值的能力，往往是通过指针来实现的。比如，实现
两整数变量值交换的c程序如下：
void swapint(int *a,int *b)
{
int temp;
temp=*a;
a=*b;
*b=temp;
}

使用引用机制后，以上程序的c++版本为：
void swapint(int &amp;a,int &amp;b)
{
int temp;
temp=a;
a=b;
b=temp;
}
调用该函数的c++方法为：swapint（x,y); c++自动把x,y的地址作为参数传递给swapint函数。

2、给函数传递大型对象
当大型对象被传递给函数时，使用引用参数可使参数传递效率得到提高，因为引用并不产生对象的
副本，也就是参数传递时，对象无须复制。下面的例子定义了一个有限整数集合的类：
const maxCard=100;
Class Set
{
int elems[maxCard]; // 集和中的元素，maxCard 表示集合中元素个数的最大值。
int card; // 集合中元素的个数。
public:
Set () {card=0;} //构造函数
friend Set operator * (Set ,Set ) ; //重载运算符号*，用于计算集合的交集 用对象作为传值参数
// friend Set operator * (Set &amp; ,Set &amp; ) 重载运算符号*，用于计算集合的交集 用对象的引用作为传值参数
...
}
先考虑集合交集的实现
Set operator *( Set Set1,Set Set2)
{
Set res;
for(int i=0;i&lt;Set1.card;++i)
for(int j=0;j&gt;Set2.card;++j)
if(Set1.elems[i]==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems[i];
break;
}
return res;
}
由于重载运算符不能对指针单独操作，我们必须把运算数声明为 Set 类型而不是 Set * 。
每次使用*做交集运算时，整个集合都被复制，这样效率很低。我们可以用引用来避免这种情况。
Set operator *( Set &amp;Set1,Set &amp;Set2)
{ Set res;
for(int i=0;i&lt;Set1.card;++i)
for(int j=0;j&gt;Set2.card;++j)
if(Set1.elems[i]==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems[i];
break;
}
return res;
}

三、引用返回值

如果一个函数返回了引用，那么该函数的调用也可以被赋值。这里有一函数，它拥有两个引用参数并返回一个双精度数的引用：
double &amp;max(double &amp;d1,double &amp;d2)
{
return d1&gt;d2?d1:d2;
}
由于max()函数返回一个对双精度数的引用，那么我们就可以用max() 来对其中较大的双精度数加1：
max(x,y)+=1.0;

 

 
C++引用与指针的比较

引用是C++中的概念，初学者容易把引用和指针混淆一起。
一下程序中，n是m的一个引用（reference），m是被引用物（referent）。
int m;
int &amp;n = m;
n相当于m的别名（绰号），对n的任何操作就是对m的操作。
所以n既不是m的拷贝，也不是指向m的指针，其实n就是m它自己。

引用的规则：

（1）引用被创建的同时必须被初始化（指针则可以在任何时候被初始化）。
（2）不能有NULL引用，引用必须与合法的存储单元关联（指针则可以是NULL）。
（3）一旦引用被初始化，就不能改变引用的关系（指针则可以随时改变所指的对象）。

以下示例程序中，k被初始化为i的引用。
语句k = j并不能将k修改成为j的引用，只是把k的值改变成为6。
由于k是i的引用，所以i的值也变成了6。
int i = 5;
int j = 6;
int &amp;k = i;
k = j; // k和i的值都变成了6;

引用的主要功能是传递函数的参数和返回值。

C++语言中，函数的参数和返回值的传递方式有三种：值传递、指针传递和引用传递。

以下是&quot;值传递&quot;的示例程序。

由于Func1函数体内的x是外部变量n的一份拷贝，改变x的值不会影响n, 所以n的值仍然是0。
void Func1(int x)
{
x = x + 10;
}
...
int n = 0;
Func1(n);
cout &lt;&lt; &quot;n = &quot; &lt;&lt; n &lt;&lt; endl; // n = 0

以下是&quot;指针传递&quot;的示例程序。

由于Func2函数体内的x是指向外部变量n的指针，改变该指针的内容将导致n的值改变，所以n的值成为10。
void Func2(int *x)
{
(* x) = (* x) + 10;
}
...
int n = 0;
Func2(&amp;n);
cout &lt;&lt; &quot;n = &quot; &lt;&lt; n &lt;&lt; endl; // n = 10

以下是&quot;引用传递&quot;的示例程序。

由于Func3函数体内的x是外部变量n的引用，x和n是同一个东西，改变x等于改变n，所以n的值成为10。
void Func3(int &amp;x)
{
x = x + 10;
}
...
int n = 0;
Func3(n);
cout &lt;&lt; &quot;n = &quot; &lt;&lt; n &lt;&lt; endl; // n = 10

对比上述三个示例程序，会发现&quot;引用传递&quot;的性质象&quot;指针传递&quot;，而书写方式象&quot;值传递&quot;。

实际上&quot;引用&quot;可以做的任何事情&quot;指针&quot;也都能够做，为什么还要&quot;引用&quot;这东西？
答案是&quot;用适当的工具做恰如其分的工作&quot;。

指针能够毫无约束地操作内存中的任何东西，尽管指针功能强大，但是非常危险。

如果的确只需要借用一下某个对象的&quot;别名&quot;，那么就用&quot;引用&quot;，而不要用&quot;指针&quot;，以免发生意外。


<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-09-05 20:40 <a href="http://www.cnblogs.com/alexusli/archive/2009/09/05/1561000.html#1637218#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: C++ 文件读于写</title><link>http://www.cnblogs.com/alexusli/archive/2009/06/21/1507535.html#1564251</link><dc:creator>AlexusLi</dc:creator><author>AlexusLi</author><pubDate>Sun, 21 Jun 2009 08:21:08 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/06/21/1507535.html#1564251</guid><description><![CDATA[#include &quot;file.h&quot;<br/>#include &lt;iostream&gt;<br/>#include &lt;fstream&gt;<br/><br/>using namespace std;<br/><br/>file::file(void)<br/>{<br/>	file::OutFilePath=&quot;C:\\file.txt&quot;;<br/>	file::StopInput=&quot;exit&quot;;<br/>}<br/>void file::CreatTextFile()<br/>{<br/>	ofstream OutFile(file::OutFilePath.c_str());<br/><br/>	cout&lt;&lt;&quot;Please input information to save:&quot;&lt;&lt;endl;<br/>	cin&gt;&gt;file::UserInputWord;<br/>	int CompResult;<br/>	CompResult=UserInputWord.compare(StopInput);<br/>	while(CompResult!=0)<br/>	{<br/>		cin&gt;&gt;file::UserInputWord;<br/>		OutFile&lt;&lt;file::UserInputWord&lt;&lt;endl;<br/>		CompResult=UserInputWord.compare(StopInput);<br/>	}<br/>	//close the fileStream hand<br/>	OutFile.close();<br/>	cout &lt;&lt;&quot;finish input and save the information.&quot;&lt;&lt;endl&lt;&lt;endl;<br/>}<br/>void file::ReadTextFile()<br/>{<br/>	cout&lt;&lt;&quot;Began invoke the readTextFile fuction.&quot;&lt;&lt;endl;<br/>	ifstream ReadFile(file::OutFilePath.c_str());<br/>	while(!ReadFile.eof())<br/>	{<br/>		getline(ReadFile,file::UserReadWord);<br/>		cout&lt;&lt;file::UserReadWord&lt;&lt;endl;<br/>	}<br/>	ReadFile.close();<br/>	cout&lt;&lt;&quot;End invoke the readTextFile fuction.&quot;&lt;&lt;endl;<br/>}<br/><br/>file::~file(void)<br/>{<br/>}<br/><br/><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">AlexusLi</a> 2009-06-21 16:21 <a href="http://www.cnblogs.com/alexusli/archive/2009/06/21/1507535.html#1564251#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>re: 在vs2005中添加lib库的方法</title><link>http://www.cnblogs.com/alexusli/archive/2009/05/14/1370976.html#1527398</link><dc:creator>boluor</dc:creator><author>boluor</author><pubDate>Wed, 13 May 2009 16:40:19 GMT</pubDate><guid>http://www.cnblogs.com/alexusli/archive/2009/05/14/1370976.html#1527398</guid><description><![CDATA[谢谢！我纠结了半天，终于找到解决方法了。我参考了你的文章。<br><br><div align=right><a style="text-decoration:none;" href="http://www.cnblogs.com/alexusli/" target="_blank">boluor</a> 2009-05-14 00:40 <a href="http://www.cnblogs.com/alexusli/archive/2009/05/14/1370976.html#1527398#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>
