??xml version="1.0" encoding="utf-8" standalone="yes"?>国产2021久久精品,国产精品VIDEOSSEX久久发布,国产福利电影一区二区三区久久久久成人精品综合 http://m.shnenglu.com/smallfa/category/8802.htmlhazh-cnTue, 09 Dec 2008 06:15:33 GMTTue, 09 Dec 2008 06:15:33 GMT60从Java到C++ ?ҎJava与C++~程的不?/title><link>http://m.shnenglu.com/smallfa/archive/2008/12/09/68932.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Tue, 09 Dec 2008 05:43:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/12/09/68932.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/68932.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/12/09/68932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/68932.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/68932.html</trackback:ping><description><![CDATA[<h2>1. 数据cd和变?/h2> <p>C++ 中的变量cd与Java很相伹{像Java一PC++ ?tt>int</tt> ?<tt>double</tt> cd。但是这些数字类型的取D围是依赖于机器的。比如在16位系l上Q例如运行DOS 或Windows 3.x的PCZQ?tt>int</tt> 是双字节(2-byte)的,取D围比Java?-byte?tt>int</tt> 要小很多。在q些机器上,如果 int 不够用的话,你需要用长整型long?/p> <p>C++ ?<tt>short</tt> ?<tt>unsigned</tt> cd来更有效的存储数字。(我认为所谓有效是指更高的I间利用率。) 最好是量避免使用q些cd除非是空间利用的有效性对你的pȝ真的非常重要?/p> <p>在C++中布型?<tt>bool</tt> 表示Q而不像在Java中用boolean?/p> <p>C++ 中字W串cd?<tt>string</tt> 表示。它与Java中的 <tt>String</tt> cd非常怼Q但是,q是要逐一以下几点不同之处Q?/p> <p>1. C++ 字符串存储ASCII 码字W,而不是标准码Unicode 字符</p> <p>2. C++ 字符串是可以被修改的Q而Java字符串的内容是不可修改的(immutable)?/p> <p>3. 取子字符串的操作?C++ 中叫?<tt>substr</tt>Q这个命?tt>s.substr(i, n)</tt> 从字W串s中取得从位置 i 开始长度ؓn的子字符丌Ӏ?/p> <p>4. 在C++中,你只能够字W串与其它字W串对象怸?concatenate)Q而不能够与Q意的对象怸联?/p> <p>5. C++中可以直接用关pL作符 <tt>==?!=?<?<=?>?>= </tt>来进行字W串比较Q其中后面四个操作符是按字母序q行比较的?q比Java中用函数equals和compareTo来比较要方便很多?/p> <br><br> <h2>2. 变量和常?/h2> <p>在C++中,本地变量的定义看h与Java中相同,例如Q?/p> <p><tt>int n = 5;</tt></p> <p>实际上这正是C++和Java的一个重要不同之处。C++~译器不Ҏ地变量进行初始化验,所以在C++中很Ҏ忘记初始化一个变量,q种情况下,变量的D变量所占内存区域中刚好当前存在随机倹{这昄是很Ҏ产生E序出错的地斏V?/p> <p>与Java一P C++中类可以有数据域和静态变量。不同的是,C++中变量可以在函数甚至是类的外面定义,q些所谓的全局变量可以在程序的M函数中被讉KQ因而不易被很好的管理。所C++中应该尽量避免用全局变量?/p> <p>在C++中,帔R可以在Q何地方被定义Q记得在Java中,帔R必须是类的静态数据static data)?C++ 使用关键?<tt>const</tt> 来定义常量,而Java中是 <tt>final</tt>。例如:</p> <p><tt>const int DAYS_PER_YEAR = 365;</tt></p> <br><br><br> <h2>3. c?/h2> <p>C++ 中对cȝ定义与Java有些不同Q这里是一个例子:一个C++ 版本?<tt>Point</tt> c?</p> <p><tt>class Point /* C++ */</tt></p> <p><tt>{</tt></p> <p><tt>public:</tt></p> <p><tt>Point();</tt></p> <p><tt>Point(double xval, double yval);</tt></p> <p><tt>void move(double dx, double dy);</tt></p> <p><tt>double getX() const;</tt></p> <p><tt>double getY() const;</tt></p> <p><tt>private:</tt></p> <p><tt>double x;</tt></p> <p><tt>double y;</tt></p> <p><tt>};</tt></p> <p>q里几点重要的不同是Q?/p> <p>1. C++的类定义中分为公共和U有部分Q分别以关键?<tt>public</tt> ?<tt>private</tt>开始。而在Java中,每一个元素都必须标明 <tt>public</tt> ?<tt>private</tt>?/p> <p>2. C++中类的定义只包含函数的声明,真正的实现另外单独列出?/p> <p>3. 讉K函数(accessor methods)标有关键?<tt>const</tt> Q表明这个函C会改变本对象的元素倹{?/p> <p>4. cd义的l尾处有分号</p> <p>cM函数的实现跟在类的定义之后。因为函数是在类外面定义的,所以每一个函数的名字前面要加cdUC为前~Qƈ使用操作W双冒号::来分割类的名U和函数的名U。不改变隐含参数|卛_前对象的|的访问函数用 <tt>const</tt>标明。如下所C是上面cd义中的函数的实现Q?/p> <p><tt>Point::Point() { x = 0; y = 0; }</tt></p> <p><tt>void Point::move(double dx, double dy) </tt></p> <p><tt>{</tt></p> <p><tt>x = x + dx;</tt></p> <p><tt>y = y + dy;</tt></p> <p><tt>}</tt></p> <p><tt>double Point::getX() const</tt></p> <p><tt>{ </tt></p> <p><tt>return x;</tt></p> <p><tt>}</tt></p> <br><br><br> <h2>4. 对象</h2> <p>Java ?C++ 最主要的不同在于对象变量的使用。在 C++中,对象变量存储的是真正的对象的|而不是对象引?<a title=关于reference的文?><u><font color=#810081>reference</font></u></a>)。注意在C++中构造一个对象的时候是不用关键字new的,只需要在变量的名字后面直接赋予构造函数的参数可以了Q例如:</p> <p><tt>Point p(1, 2); /* 构造对?p */</tt></p> <p>如果不跟参数赋|则用默认构造函敎ͼ例如Q?/p> <p><tt>Time now; /* 默认使用构造函?Time::Time() */</tt></p> <p>q一点与Java很不同。在Java中,q个命o仅仅生成一个没有初始化的referenceQ而在C++中,它生成一个实际的对象?/p> <p>当一个对象被赋给另一个对象变量的时候,实际的值将被拷贝。而在Java中,拯一个对象变量只不过是徏立了另外一个指向对象的reference。拷贝一个C++的对象就像在Java中调用cloneq个函数一P而修Ҏ贝的g会改变原对象的倹{例如:</p> <p><tt>Point q = p; /* 拯p到q */</tt></p> <p><tt>q.move(1, 1); /* Udq而p不动Q即q的值变了,而p的不?/</tt></p> <p>多数情况下,C++中这U对象直接对值操作的Ҏ用v来很方便Q但是也有些时候不如人意Q?/p> <p>1. 当需要一个函C修改一个对象的|必须C要用按引用调用call by reference (参见下面函数部分)</p> <p>2. 两个对象变量不能指向同一个对象实体。如果你要在C++中实现这U效果,必须使用指针pointerQ参见下面指针部分)</p> <p>3. 一个对象变量只能存储一U特定的cd的|如果你想要用一个变量来存储不同子类的对象的|多态ploymorphism)Q则需要用指针?/p> <p>4. 如果你想在C++中用一个变量来或者指向null或者指向一个实际的对象Q则需要用指?/p> <br><br><br><br><br> <h2>5. 函数</h2> <p>在Java中,每一个函数必L者是对象函数(instance method)Q或者是静态函?static function)或称cd数。C++同样支持对象函数和静态函敎ͼcd敎ͼQ但同时C++也允许定义不属于Mcȝ函数Q这些函数叫做全局函数<em>Qglobal functionsQ?/em>?/p> <p>特别的是Q每一个C++ E序都从一个叫?<tt>main</tt>的全局函数开始执行:</p> <p><tt>int main()</tt></p> <p><tt>{ . . .</tt></p> <p><tt>}</tt></p> <p>q有另外一个格式的main函数可以用来捕捉命o行参敎ͼcM于Java的main函数Q但是它要求关于C格式的数l和字符串的知识Q这里就不介l了?/p> <p>按照习惯Q通常如果E序执行成功Q?<tt>main</tt> 函数q回0Q否则返回非零整数?/p> <p>同Java一P函数参数是通过g递的(passed by value)。在Java中,函数无论如何都是可以修改对象的值的。然而在C++中,因ؓ对象直接存储的是实际的|而不是指向值的referenceQ也是说传入函数的是一个实际值的拯Q因此也无法修改原来对象的倹{?/p> <p>所以,C++ 有两U参C递机Ӟ同Java一L按D?<em>call by value) </em>Q以及按地址调用(<em>call by reference</em>)。当一个参数是按reference传递时Q函数可以修改其原始倹{Call by reference 的参数前面有一个地址?<tt>&</tt> 跟在参数cd的后面,例如Q?/p> <p><tt>void raiseSalary(Employee& e, double by)</tt></p> <p><tt>{ . . .</tt></p> <p><tt>}</tt></p> <p>下面是一个典型的利用call by reference的函敎ͼ在Java中是无法实现q样的功能的?/p> <p><tt>void swap(int& a, int& b)</tt></p> <p><tt>{ int temp = a;</tt></p> <p><tt>a = b;</tt></p> <p><tt>b = temp;</tt></p> <p><tt>}</tt></p> <p>如果使用 <tt>swap(x, y)</tt>来调用这个函敎ͼ则reference参数 <tt>a</tt> ?<tt>b</tt> 指向原实际参?tt>x</tt> ?<tt>y</tt>的位|,而不是它们的值的拯Q因此这个函数可以实现实际交换这两个参数的倹{?/p> <p>?C++中,每当需要实C改原参数的值时你就可以使用按地址调用 call by reference </p> <br><br><br> <h2>6. 向量Vector</h2> <p>C++ 的向量结构结合了Java中数l和向量两者的优点。一个C++ 的向量可以方便的被访问,其容量又可以动态的增长。如?<tt>T</tt> 是Q意类型,?<tt>vector<T></tt> 是一个元素ؓ <tt>T</tt> cd的动态数l。下面的语句</p> <p><tt>vector<int> a;</tt></p> <p>产生一个初始ؓI的向量。而语?/p> <p><tt>vector<int> a(100);</tt></p> <p>生成一个初始有100个元素的向量。你可以使用<tt>push_back</tt> 函数来添加元素:</p> <p><tt>a.push_back(n);</tt></p> <p>调用 <tt>a.pop_back()</tt> ?tt>a</tt>中取出最后一个元素(操作后这个元素被从a中删?Q?使用函数<tt>size</tt> 可以得到当前a中的元素个数?/p> <p>你还可以通过我们熟悉?<tt>[]</tt> 操作W来讉K向量中元素,例如Q?/p> <p><tt>for (i = 0; i < a.size(); i++) {<br></tt></p> <p><tt>sum = sum + a[i];</tt></p> <p><tt>}</tt></p> <p>同Java中一P数组索引必须?0 ?<tt>a.size() - 1</tt>之间的倹{但是与Java不同的是QC++中没有runtime的烦引号合法性检验。试图访问非法的索引位置可能造成非常严重的出错?/p> <p>像所有其?C++ 对象一P向量也是倹{如果你一个向量赋值给另外一个向量变量,所有的元素都会被拷贝过厅R?/p> <p><tt>vector<int> b = a; /* 所有的元素都被拯?*/</tt></p> <p>ҎJava中的情况Q在Java中,一个数l变量是一个指向数l的reference。拷贝这个变量仅仅生另外一个指向同一数组的referenceQ而不会拷贝每一个元素的倹{?/p> <p>正因如此Q如果一个C++函数要实C改向量的|必须使用reference参数Q?/p> <p><tt>void sort(vector<int>& a)</tt></p> <p><tt>{ . . .</tt></p> <p><tt>}</tt></p> <br><br><br> <h2>7. 输入和输?/h2> <p>在C++中,标准的输入输出流用对?<tt>cin</tt> ?<tt>cout</tt> 表示。我们?<tt><<</tt> 操作W写输出Q例如:</p> <p><tt>cout << “Hello, World!”;</tt></p> <p>也可以连着输出多项内容Q例如:</p> <p><tt>cout << “The answer is ” << x << “\n”;</tt></p> <p>我们使用 <tt>>></tt> 操作W来d一个数字或单词Q例如:</p> <p><tt>double x;</tt></p> <p><tt>cout << “Please enter x: “;</tt></p> <p><tt>cin >> x;</tt></p> <p><tt>string fname;</tt></p> <p><tt>cout << “Please enter your first name: “;</tt></p> <p><tt>cin >> fname;</tt></p> <p>函数<tt>getline</tt> 可以d整行的输入,例如Q?/p> <p><tt>string inputLine;</tt></p> <p><tt>getline(cin, inputLine);</tt></p> <p>如果到达输入的结,或者一个数字无法被正确的读入,q个对象会被设|ؓ failed 状态,我们可以使用函数 <tt>fail</tt> 来检验这个状态,例如Q?/p> <p><tt>int n;</tt></p> <p><tt>cin >> n;</tt></p> <p><tt>if (cin.fail()) cout << “Bad input”;</tt></p> <p>一旦一个流的状态被设ؓfailedQ我们是很难重置它的状态的Q所以如果你的程序需要处理错误输入的情况Q应该用函?<tt>getline</tt> 然后人工处理得到的输入数据?/p> <p> </p> <p> </p> <br><br> <h2>8. 指针pointer</h2> <p>我们已经知道在C++中,对象变量直接存储的是对象的倹{这是与Java不同的,在Java中对象变量存储的是一个地址Q该地址指向对象值实际存储的地方。有时在C++中也需要实现这L布置Q这qC指针pointer。在 C++中,一个指向对象的变量叫做指针。如果T是一U数据类型,?<tt>T*</tt> 是指向这U数据类型的指针?/p> <p>像 Java中一P一个指针变量可以被初始化ؓI?<tt>NULL</tt>Q另外一个指针变量的|或者一个调用new生成的新对象Q?/p> <p><tt>Employee* p = NULL;</tt></p> <p><tt>Employee* q = new Employee(”Hacker, Harry”, 35000);</tt></p> <p><tt>Employee* r = q;</tt></p> <p>实际上在C++中还有第四种可能Q那是指针可以被初始化为另外一个对象的地址Q这需要用地址操作W?<tt>&</tt> Q?/p> <p><tt>Employee boss(”Morris, Melinda”, 83000);</tt></p> <p><tt>Employee* s = &boss;</tt></p> <p>q实际上q不是什么好L。保险的做法q是应该直接让指针指向?<tt>new</tt>生成的新对象?/p> <p>到目前ؓ止,C++ 指针看v来非常像 Java 的对象变量。然而,q里有一个很重要的语法的不同。我们必M用星h作符 <tt>*</tt> 来访问指针指向的对象。如?<tt>p</tt> 是一个指?tt>Employee</tt>对象的指针,?<tt>*p</tt> 才代表了q个对象Q?/p> <p><tt>Employee* p = . . .;</tt></p> <p><tt>Employee boss = <strong>*p</strong>;</tt></p> <p>当我们需要执行对象的函数或访问对象的一个数据域Ӟ也需要?<tt>*p</tt> Q?/p> <p><tt>(*p).setSalary(91000);</tt></p> <p>*p外面的括h必需的,因ؓ <tt>.</tt> 操作W比 * 操作W有更高的优先。C的设计者觉得这U写法很隄Q所以他们提供了另外一U替代的写法Q?-> 操作W来实现 <tt>*</tt> ?<tt>.</tt> 操作W的l合功能。表辑ּ</p> <p><tt>p->setSalary(91000);</tt></p> <p>可以调用对象*p的函?<tt>setSalary</tt> 。你可以单的C <tt>.</tt> 操作W是在对象上使用的,-> 操作W是在指针上使用的?/p> <p>如果你不初始化一个指针,或者如果一个指针ؓI?NULL 或指向的对象不再存在Q则在它上面使用 <tt>*</tt> ?<tt>-></tt> 操作W就会出错?不幸的是 C++ runtime pȝq不查这个出错。如果你范了q个错误Q你的程序可能会行ؓ古怪或L?/p> <p>而在Java中,q些错误是不会发生的。所有的reference都必d始化Q所有的对象只要仍有reference指向它就不会被从内存中清除,因此你也不会有一个指向已被删除的对象的reference。Java的runtime pȝ会检查reference是否为空Qƈ在遇到空指针时抛Z个null pointer的例?exception)?/p> <p>C++ ?Javaq有一个显著的不同Q就?Java ?em>垃圾回收</em>功能Q能够自动回收被废弃的对象。而在C++中,需要程序员自己理内存分配回收?/p> <p>C++中当对象变量出范围时可以自动被回收。但是用new生成的对象必ȝdelete操作W手动删除,例如Q?/p> <p><tt>Employee* p = new Employee(”Hacker, Harry”, 38000);</tt></p> <p><tt>. . .</tt></p> <p><tt>delete p; /* 不在需要这个对?*/</tt></p> <p>如果你忘记删除一个对象,那么你的E序有可能最l用光所有内存。这是我们常说的内存泄?(<em>memory leak</em>)。更重要的是Q如果你如果删除了一个对象,然后又l用它Q你可能覆盖不属于你的数据。如果你刚y覆盖了用于处理内存回收的数据域,那么内存分配机制可能运转失常而造成更严重的错误Q而且很难诊断和修复。因此,在C++中最好尽量少用指?/p> <br><br><br> <h2>9. l承</h2> <p>C++和Java中承的基本语法是很怼的。在C++中,使用 <tt>: public</tt> 代替Java中的<tt>extends</tt> 来表C承关p??(C++ 也支持私有承的概念Q但是不太有用?</p> <p>默认情况下,C++中的函数不是动态绑定的。如果你需要某个函数实现动态绑定,需要?tt>virtual</tt>声明它ؓ虚函敎ͼ例如Q?/p> <p><tt>class Manager : public Employee</tt></p> <p><tt>{ </tt></p> <p><tt>public:</tt></p> <p><tt>Manager(string name, double salary, string dept);</tt></p> <p><tt><strong>virtual</strong> void print() const;</tt></p> <p><tt>private:</tt></p> <p><tt>string department;</tt></p> <p><tt>};</tt></p> <p>同Java一P构造函C调用父类的构造函数有Ҏ的语法?Java使用关键?<tt>super</tt>。C++中必d子类的构造函C外调用父cȝ构造函数。下面是一个例子:</p> <p><tt>Manager::Manager(string name, double salary, string dept)</tt></p> <p><tt><strong>: Employee(name, salary) </strong>/* 调用父类的构造函?*/</tt></p> <p><tt>{ department = dept;</tt></p> <p><tt>}</tt></p> <p>Java 中在子类函数中调用父cȝ函数时也使用关键?<tt>super</tt> 。而在C++中是使用父类的名U加上操作符 <tt>::</tt>表示Q例如:</p> <p><tt>void Manager::print() const</tt></p> <p><tt>{ <strong>Employee::print(); </strong>/* 调用父类的函?*/</tt></p> <p><tt>cout << department << “\n”;</tt></p> <p><tt>}</tt></p> <p>一?C++ 对象变量只能存储特定cd的对象倹{要惛_C++中实现多?polymorphism)Q必M用指针。一?<tt>T*</tt> 指针可以指向cd?<tt>T</tt> ?<tt>T</tt> 的Q意子cȝ对象Q例如:</p> <p><tt>Employee* e = new Manager(”Morris, Melinda”, 83000, “Finance”);</tt></p> <p>你可以将父类和不同子cȝ对象混合攉C个元素均为指针的向量中,然后调用动态绑定的函数Q如下所C:</p> <p><tt>vector<Employee*> staff;</tt></p> <p><tt>. . .</tt></p> <p><tt>for (i = 0; i < staff.size(); i++)</tt></p> <p><tt>staff[i]->print();</tt></p> <img src ="http://m.shnenglu.com/smallfa/aggbug/68932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-12-09 13:43 <a href="http://m.shnenglu.com/smallfa/archive/2008/12/09/68932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正确的方法是定义operator++以reference为参数类? C++中Reference与指针(PointerQ的使用Ҏhttp://m.shnenglu.com/smallfa/archive/2008/12/09/68928.htmlhenry08henry08Tue, 09 Dec 2008 05:16:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/09/68928.htmlhttp://m.shnenglu.com/smallfa/comments/68928.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/09/68928.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/68928.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68928.htmlday &operator++(day &d)
{
d = (day)(d + 1);
return d;
}

使用q个函数Q?表达?++x 才有正确的显CZ及正的操作?br>Passing by reference不仅仅是写operator++较好的方法,而是唯一的方法?br>

 C++在这里ƈ没有l我们选择的余地?br> 像下面的声明:
day *operator++(day *d);
是不?通过~译的?br>每个重蝲的操作符函数必须或者是一个类的成员, 或者用类型T?T & ?T const & 为参数类型,
q里T是一个类(class)或列?enumeration)cd?

也就是说Q每一个重载操作符必须以类或列丄型ؓ参数cd?br>
指针Q即使是指向一个类或列丄型对象的指针Q也不可以用?br>
C++ 不允许在重蝲操作W时重新定义内置操作W的含义Q包括指针类型?br>因此Q我们不可以定义Q?br>int operator++(int i); // 错误
因ؓ它试囑֯int重新定义操作W?++ 的含义?我们也不可以定义Q?br>int *operator++(int *i); // 错误
因ؓ它试囑֯ int * 重新定义操作W?++ 的含?br>

 

 

References vs. const pointers

C++ 中不允许定义”const reference”Q?br> 因ؓ一个reference天生是const。也是_一旦将一个referencel定C个对象,无法再它重新l定到另一个不同的对象?br>在声 明一个reference之后没有写法可以它重新l定到另外一个对象?br>例如Q?br>int &ri = i;
?ri l定?i 。然后下面的赋?
ri = j;
q不是把 ri l定?j Q而是?j 中的Dl?ri 指向的对象,也就是赋l?i ?br>


而言之,
一个pointer在它的有生之q可以指向许多不同的对象Q?br>而一个reference只能够指向一个对象?br>有些才是 reference?pointer最大的不同?br>我ƈ不赞成。也许这是reference与pointer的一点不同, 但ƈ不是reference和const pointer的不同?br>在强调一遍,一旦一个reference与一个对象绑定,׃能再它Ҏ向另外的东西?br>既然不能再绑定reference之后?改变Q?一个reference必d一出生pl定?br>否则q个reference永q不能被l定CQ何东西,也就毫无用处了?/p>

上一D늚讨论也同样完全适用于常量指针(const pointerQ?br>Q注意,我这里说的是帔R指针Qconst pointerQ, 而不是指向常量的指针 “pointers to const”?
 例如Q?br>一个reference声明必须同时带有一个初始化赋|如下所C:

void f()
{
int &r = i;

}

省略q个初始化赋值将产生一个编译错误:

void f()
{
int &r; //错误

}

一个常量指针的声明也同样必d有一个初始化赋|如下所C:

void f()
{
int *const p = &i;

}

省略q个初始化赋值同样会出错Q?/p>

void f(){
int *const p; // 错误

}

在我看来
不能够对reference二次l定作ؓreference与pointer的不同?br>q不比常量指针和非常量指针的不同更ؓ显著?br>



Null references

除了昄的不同,帔R指针与referenceq有一炚w怸同,那就是,一个有效的reference必须指向一个对象;而一个指针不需要。一个指针,即是一个常量指针, 都可以有I倹{?一个空指针不指向Q何东ѝ?/p>

q点不同暗C当你想要确信一个参数必L向一个对象的时候,应该使用reference作ؓ参数cd?例如Q交换函?swap function)Q它接受两个int参数Qƈ两个参数的数值对调,如下所C:

int i, j;
swap(i, j);

原本在 i 中的值放?j 中, q将原本?j 中的值放?i 中。我们可以这样写q个函数Q?/p>

void swap(int *v1, int *v2)
{
int temp = *v1;
*v1 = *v2;
*v2 = temp;
}

q种定义下,函数要像q样被调? swap(&i, &j);

q个接口暗示其中一个或两个参数都有可能为空(null)。而这个暗C是误导的。例如,调用
swap(&i, NULL);
的后果很可能是不愉快的?/p>

而像下面q样定义reference为参敎ͼ

void swap(int &v1, int &v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}

清晰的表明了调用swap应该提供两个对象Q它们的值将被交换?q且q样定义的另一个好处是Q在调用q个函数的时候,不需要用那?amp;W号Q看h更顺|
swap(i, j);








 

Null references

除了昄的不同,
帔R指针与referenceq有一炚w怸同,
那就是,一个有效的reference必须指向一个对象;

?span style="COLOR: red">一个指针不需?/span>?br>一个指针,即是一个常量指针, 都可以有I倹{?一个空指针不指向Q何东ѝ?br>

q点不同暗C当你想要确信一个参数必L向一个对象的时候,应该使用reference作ؓ参数cd?/span>
 例如Q?br>交换函数(swap function)Q它接受两个int参数Qƈ两个参数的数值对调,如下所C:

int i, j;
swap(i, j);

原本在 i 中的值放?j 中, q将原本?j 中的值放?i 中。我们可以这样写q个函数Q?/p>

void swap(int *v1, int *v2)
{
int temp = *v1;
*v1 = *v2;
*v2 = temp;
}

q种定义下,函数要像q样被调? swap(&i, &j);

q个接口暗示其中一个或两个参数都有可能为空(null)。而这个暗C是误导的。例如,调用
swap(&i, NULL);
的后果很可能是不愉快的?/p>

而像下面q样定义reference为参敎ͼ

void swap(int &v1, int &v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}

清晰的表明了调用swap应该提供两个对象Q它们的值将被交换?q且q样定义的另一个好处是Q在调用q个函数的时候,不需要用那?amp;W号Q看h更顺|
swap(i, j);


更安?


有些为既然reference不能够ؓI,那么它应该比指针更安全?br> 我认为reference可能要安全一点,但不会安全很多?br>虽然一个有效的reference不能为空Q但是无效的可以呀?br>实际上,在很多情况下E序有可 能生无效的referenceQ而不只是I的reference?/span>

 例如Q?/span>
你可以定义一个referenceQ它绑定到一个指针指向的对象Q如下所C:

int *p;

int &r = *p;

如果指针*p在reference定义时刚好ؓI,则这个reference为空?br> 从技术上来说Q这个错误ƈ不在于将referencel定C个空|而是在于对一个空指针d考?br> 对一个空指针d考生了一个不定的操作,也就意味着很多事都可能发生Q而且大部分都不是什么好事。很有可能当E序reference r l定?p (p所指向的对?的时候,p实际上没有被d考,甚至E序只是p的值拷贝给实现r的指针?br>而程序将会l执行下ȝ到错误在后面的运行中更ؓ明显的表 现出来,产生不可预知的危実?/p>

下面的函?br>展示?br>另外一U生无效reference的方法:

int &f()
{
int i;

return i;
}

q个函数q回一个指向本地变?i 的reference?br>然而当函数q回Ӟ本地变量 i 的存储空间也消׃。因此这个函数实际返回了一个指向被回收了的I间的reference。这个操作与q回一个指向本地变量的指针的后果相同?br>有些~译 器可以在~译时发现这个错误,但也很有可能不会发现?br>



我喜ƢreferenceQ也有很好的理由使用它们代替pointer?br>
但如果你期望使用reference来你的E序健壮性显著增强,那么你多半会失望?br>


参考资料:

  1. Saks, Dan. “Introduction to References,” Embedded Systems Programming, January 2001, p. 81.
  2. Saks, Dan. “References and const“, Embedded Systems Programming February 2001, p. 73.


henry08 2008-12-09 13:16 发表评论
]]>
VC6.0中重载操作符函数无法讉KcȝU有成员http://m.shnenglu.com/smallfa/archive/2008/12/08/68892.htmlhenry08henry08Mon, 08 Dec 2008 15:50:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/08/68892.htmlhttp://m.shnenglu.com/smallfa/comments/68892.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/08/68892.html#Feedback2http://m.shnenglu.com/smallfa/comments/commentRss/68892.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68892.html?C++ 中,操作W?q算W)可以被重载以改写其实际操作?br>同时我们可以定义一个函Cؓcȝ朋友函数(friend function)以便使得q个函数能够讉KcȝU有成员Q?br>q个定义通常在头文g中完成?/p>

在Visual C++中定义一般的函数为朋友函数通常是没有问题的?br>然而对某些重蝲操作W的函数Q?br>即我们它们定义ؓcȝ朋友函数QVC的编译器仍然会显C出错信息,
认ؓq些朋友函数无权讉KcȝU有成员?br>我认应该是VC6.0的bug?br>

以下代码是个例?

// 头文?“Sample.h”
            #include<iostream>
            using namespace std;
            class Sample {
            public:
            Sample();
            friend ostream &operator<<(ostream &out, const Sample s);
            friend istream &operator>>(istream &in, Sample & s);
            private:
            int x;
            };

// 实现文g “Sample.cpp”
            #include “Sample.h”
            Sample::Sample() {
            x=0;
            }
            istream &operator>>(istream &in, Sample & s) {
            cout<<”Please enter a value”<<endl;
            in >> s.x ;
            return in;
            }
            ostream &operator<<(ostream &out, const Sample s) {
            cout << s.x << endl;
            return out;
            }

以上代码在gnuc++中编译运行毫无问题。但是在VC++6.0中编译的时候就会出C下的~译错误Q?/p>
Compiling…
Sample.cpp
c:\temp\sample.cpp(8) : error C2248: ‘x’ : cannot access private member declared in class ‘Sample’
c:\temp\sample.h(19) : see declaration of ‘x’
c:\temp\sample.cpp(13) : error C2248: ‘x’ : cannot access private member declared in class ‘Sample’
c:\temp\sample.h(19) : see declaration of ‘x’
Error executing cl.exe.Sample.obj - 2 error(s), 0 warning(s)

在VC++ 6.0中解册个问题有以下几种ҎQ?/p>

  • 在头文g中实C为朋友函数的操作W函数的重蝲Q也是说在实现文g”Sample.cpp”中将函数重蝲的实现去掉,而将头文件修改如下:
    // 修改后的头文?1 “Sample.h”
                    #include<iostream>
                    using namespace std;
                    class Sample {
                    public:
                    Sample();
                    friend ostream &operator<<(ostream &out, const Sample s);
                    friend ostream &operator<<(ostream &out, const Sample s) {
                    cout << s.x << endl;
                    return out;
                    }
                    friend istream &operator>>(istream &in, Sample & s);
                    friend istream &operator>>(istream &in, Sample & s) {
                    cout<<”Please enter a value”<<endl;
                    in >> s.x ;
                    return in;
                    }
                    private:
                    int x;
                    };
    
        
  • 在头文g中类定义之前类和朋友操作符函数的原型特别声明一下,也就是将头文件修改如?实现文g”Sample.cpp”不用作Q何修?Q?br>
    // 修改后的头文?2 “Sample.h”
                    #include<iostream>
                    using namespace std;
                    // 以下3行代码ؓ新加?
                    class Sample;
                    ostream &operator<<(ostream &out, const Sample s);
                    istream &operator>>(istream &in, Sample & s);
                    class Sample {
                    public:
                    Sample();
                    friend ostream &operator<<(ostream &out, const Sample s);
                    friend istream &operator>>(istream &in, Sample & s);
                    private:
                    int x;
                    };
    
        
  • W三U方法是对I/O名空间的使用实行明确声明Q也是说在头文?#8221;Sample.h”中直接写Q?br>#include<iostream>
    using std::ostream;
    using std::istream
    ….
    取代 “using namespace std;”
    注意Q在q个例子里我们在实现文g “Sample.cpp”中包?“using namespace std;”q句话,否则在实C׃能?“cout” , “cin”, “<< “, “>>” ?endl q些关键字和W号。修改后的完整代码如下:

     

    // Sample.h
                    #include<iostream>
                    using std::istream;
                    using std::ostream;
                    class Sample {
                    public:
                    Sample();
                    friend ostream &operator<<(ostream &out, const Sample s);
                    /*friend ostream &operator<<(ostream &out, const Sample s) {
                    cout << s.x << endl;
                    return out;
                    }*/
                    friend istream &operator>>(istream &in, Sample & s);
                    /*friend istream &operator>>(istream &in, Sample & s) {
                    cout<<”Please enter a value”<<endl;
                    in >> s.x ;
                    return in;
                    }*/
                    private:
                    int x;
                    };
    // “Sample.cpp”
                    #include “Sample.h”
                    using namespace std;
                    Sample::Sample() {
                    x=5;
                    }
                    istream &operator>>(istream &in, Sample & s) {
                    cout<<”Please enter a value”<<endl;
                    in >> s.x ;
                    return in;
                    }
                    ostream &operator<<(ostream &out, const Sample s) {
                    cout << s.x << endl;
                    return out;
                    }
    
        


henry08 2008-12-08 23:50 发表评论
]]>
cd转换高 (Advacned Class Type-casting)http://m.shnenglu.com/smallfa/archive/2008/12/08/68836.htmlhenry08henry08Mon, 08 Dec 2008 04:58:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/08/68836.htmlhttp://m.shnenglu.com/smallfa/comments/68836.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/08/68836.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/68836.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68836.htmlreinterpret_cast

reinterpret_cast 可以一个指针{换ؓL其它cd的指?/span>?br>它也可以用来一个指针{换ؓ一个整型,或反之亦然?/p>

q个操作W可以在互不相关的类之间q行指针转换Q?br>操作的结果是单的一个指针的二进制数?binary copy)复制到另一个指针?br>Ҏ针指向的内容不做M查或转换?br>

例如Q?/p>

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);

reinterpret_cast Ҏ有指针的处理与传l的cd转换W所作的一模一栗?br>
_________________________________________________________________

static_cast

static_cast 可以执行所有能够隐含执行的cd转换Q以及它们的反向操作Q即使这U方向操作是不允讔R含执行的Q?/p>

用于cȝ指针Q也是_它允许将一个引申类的指针{换ؓ其基cȝ型(q是可以被隐含执行的有效转换Q,同时也允许进行相反的转换Q将一个基c{换ؓ一个引申类cd?/p>

在后面一U情况中Q?span style="COLOR: red">不会查被转换的基cL否真正完全是目标cd?/span>。例如下面的代码是合法的Q?/p>

class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast(a);

static_cast除了能够对类指针q行操作Q还可以被用来进行类中明定义的转换Q以及对基本cd的标准{换:

double d=3.14159265;
int i = static_cast<int>(d);

译者注Q如果你对这部分看不太懂Q请l合下面的dynamic_cast一LQ也怼帮助理解?/p>











dynamic_cast

dynamic_cast 完全被用来进行指针的操作。它可以用来q行M可以隐含q行的{换操作以及它们被用于多态类情况下的方向操作?br>
然而与static_cast不同的是Q?br> dynamic_cast 会检查后一U情늚操作是否合法Q?br>也就是说它会查类型{换操作是否会q回一个被要求cd的有效的完整的对象?/span>

q种查是在程序运行过E中q行的。如果被转换的指针所指向的对象不是一个被要求cd的有效完整的对象Q返回值将会是一个空指针NULL ?/p>

   class Base { virtual dummy(){}; };
class Derived : public Base { };


Base* b1 = new Derived;
Base* b2 = new Base;
Derived* d1 = dynamic_cast(b1); // succeeds Derived* d2 = dynamic_cast(b2); // fails: returns NULL

如果cd转换被用在引?reference)cd上,而这个{换不可能q行的话Q一个bad_cast cd的例?exception)会被抛出:

  class Base { virtual dummy(){}; };
class Derived : public Base { };

Base* b1 = new Derived;
Base* b2 = new Base;
Derived d1 = dynamic_cast(b1); // succeeds Derived d2 = dynamic_cast(b2); // fails: exception thrown








const_cast

q种cd转换对常量const q行讄或取消操作:

class C {};
const C * a = new C;
C * b = const_cast<C*> (a);

其他3Ucast 操作W都不可以修改一个对象的帔R属?constness)?/p>




typeid

ANSI-C++ q定义了一个新的操作符叫做 typeid Q?br>它检查一个表辑ּ的类型:

typeid (expression)

q个操作W返回一个类型ؓtype_info的常量对象指针,q种cd定义在标准头函数中。这U返回值可以用操作W?== ?!= 来互相进行比较,
也可以用来通过name()函数获得一个描q数据类型或cdU的字符Ԍ

例如Q?/typeinfo>

    // typeid, typeinfo
            #include <iostream.h>
            #include <typeinfo>
            class CDummy { };
            int main () {
            CDummy* a,b;
            if (typeid(a) != typeid(b)) {
            cout << "a and b are of different types:\n";
            cout << "a is: " << typeid(a).name() << '\n';
            cout << "b is: " << typeid(b).name() << '\n';
            }
            return 0;
            }
            
a and b are of different types:
a is: class CDummy *
b is: class CDummy




henry08 2008-12-08 12:58 发表评论
]]>
名空?(Namespaces)http://m.shnenglu.com/smallfa/archive/2008/12/08/68833.htmlhenry08henry08Mon, 08 Dec 2008 04:33:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/08/68833.htmlhttp://m.shnenglu.com/smallfa/comments/68833.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/08/68833.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/68833.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68833.html标准名空?Namespace std)


 

我们能够扑ֈ的关于名I间的最好的例子是标准C++ 函数库本w?br>
如ANSI C++ 标准定义Q?br>标准C++库中的所有类、对象和函数都是定义在名I间std下面的?br>

你可能已l注意到Q我们在q个教程中全部忽略了q一炏V作者决定这么做是因条规则几乎和ANSI 标准本n一样年?(1997) Q许多老一点的~译器ƈ不兼容这条规则?br>

几乎所有的~译器,即是那些与ANSI 标准兼容的编译器Q都允许使用传统的头文g (如iostream.h, stdlib.h, {等)Q就像我们在q个教程中所使用的一栗?br>

然而,ANSI标准完全重新设计了这些函数库Q?br>利用了模板功能,
而且遵@了这条规则将所有的函数和变量定义在了名I间std下?br>

该标准ؓq些头文件定义了新的名字Q对针对C++的文件基本上是用同L名字Q但没有.h的扩展名Q?br>
例如, iostream.h 变成了iostream?/p>

如果我们使用ANSI-C++ 兼容的包含文Ӟ我们必须C所有的函数、类和对象是定义在名I间 std 下面的,例如Q?/p>

    // ANSI-C++ compliant hello world
            #include <iostream>
            int main () {
            std::cout << "Hello world in ANSI-C++\n";
return 0;
}
Hello world in ANSI-C++

更常用的Ҏ是用using namespace Q这h们就不必在所有标准空间中定义的函数或对象前面L使用范围操作W?:?Q?/p>

    // ANSI-C++ compliant hello world (II)
            #include <iostream>
            using namespace std;
            int main () {
            cout << "Hello world in ANSI-C++\n";
            return 0;
            }
            
Hello world in ANSI-C++

对于STL 用户Q强烈徏议用ANSI-compliant 方式来包含标准函数库?



henry08 2008-12-08 12:33 发表评论
]]>
模板与多文g工程http://m.shnenglu.com/smallfa/archive/2008/12/08/68830.htmlhenry08henry08Mon, 08 Dec 2008 04:03:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/08/68830.htmlhttp://m.shnenglu.com/smallfa/comments/68830.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/08/68830.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/68830.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68830.html

template <class T> // 最常用的:一个class 参数?/font>

template <class T, class U> // 两个class 参数?/font>

template <class T, int N> // 一个class 和一个整数?/font>

template <class T = char> // 有一个默认倹{?/font>

template <int Tfunc (int)> // 参数Z个函数?/font>

从编译器的角度来看,模板不同于一般的函数或类?br>它们在需要时才被~译(compiled on demand)Q?br>也就是说一个模板的代码直到需要生成一个对象的时?instantiation)才被~译?br>当需要instantiation的时候,~译器根据模板ؓ特定的调用数据类型生成一个特D的函数?br>

当工E变得越来越大的时候,E序代码通常会被分割为多个源E序文g?br>在这U情况下Q?span style="COLOR: red">通常接口(interface)和实?implementation)是分开?/span>?br>

用一个函数库做例?br>     接口通常包括所有能被调用的函数的原型定义?br>                                    它们通常被定义在?h 为扩展名的头文g (header file) 中;
      而实?(函数的定? 
                                    则在独立的C++代码文g中?br>

模板q种cM?macro-like) 的功能,对多文g工程有一定的限制Q?/span>
函数或类模板的实?(定义) 必须与原型声明在同一个文件中?br>也就是说我们不能?接?interface)存储在单独的头文件中Q?br>而必d接口和实现放在用模板的同一个文件中?/p>

回到函数库的例子Q如果我们想要徏立一个函数模板的库,我们不能再用头文g(.h) Q取而代之,我们应该生成一个模板文?template file)Q将函数模板的接口和实现 都放在这个文件中 (q种文g没有惯用扩展名,除了不要使用.h扩展名或不要不加M扩展??br>

在一个工E中多次包含同时h声明和实现的模板文gq不会生链接错?(linkage errors)Q因为它们只有在需要时才被~译Q而兼Ҏ板的~译器应该已l考虑到这U情况,不会生成重复的代码?/span>



henry08 2008-12-08 12:03 发表评论
]]>
静态成?Static members)http://m.shnenglu.com/smallfa/archive/2008/12/04/68578.htmlhenry08henry08Thu, 04 Dec 2008 10:34:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/12/04/68578.htmlhttp://m.shnenglu.com/smallfa/comments/68578.htmlhttp://m.shnenglu.com/smallfa/archive/2008/12/04/68578.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/68578.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/68578.html



C++ 标准Qؓ了避免它们被多次重复声明Q?br>在class的声明中只能够包括static member的原?声明)Q?br>而不能够包括其定?初始化操??br>Z初始化一个静态数据成员,
我们必须在class之外(在全域范围内)Q?br>包括一个正式的定义Q就像上面例子中做法一栗?/span>




在提醒一ơ,它其实是一个全域变量。唯一的不同是它的名字跟在class的后面?/p>

像我们会在class中包含static数据一P我们也可以它包含static 函数?br>它们表示相同的含义:static函数是全域函?global functions)Q但是像一个指定class的对象成员一栯调用?br>它们只能够引用static 数据Q永q不能引用class的非静?nonstatic)成员?br>它们也不能够使用关键字thisQ因为this实际引用了一个对象指针,
但这?static函数却不是Q何object的成员,而是class的直接成员?/p>

henry08 2008-12-04 18:34 发表评论
]]>
定义一个class而没有明定义构造函数的时候,~译器会自动假设两个重蝲的构造函?/title><link>http://m.shnenglu.com/smallfa/archive/2008/12/04/68576.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Thu, 04 Dec 2008 10:04:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/12/04/68576.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/68576.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/12/04/68576.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/68576.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/68576.html</trackback:ping><description><![CDATA[<p>实际上,当我们定义一个class而没有明定义构造函数的时候,<br><br><br>~译器会自动假设两个重蝲的构造函?br> (默认构造函?default constructor" 和复制构造函?copy constructor")?br><br><br>例如Q对以下classQ?/p> <code> <pre> class CExample {<br> public:<br> int a,b,c;<br> void multiply (int n, int m) { a=n; b=m; c=a*b; };<br> };<br> </pre> <p>没有定义构造函敎ͼ<br><br><br>~译器自动假讑֮有以下constructor 成员函数Q?/p> <ul> <li><span style="COLOR: red">Empty constructor</span> <p>它是一个没有Q何参数的构造函敎ͼ被定义ؓnop (没有语句)。它什么都不做?/p> <code>CExample::CExample () { };</code> <li> <li><span style="COLOR: red">Copy constructor</span> <p style="COLOR: #0000ff">它是一个只有一个参数的构造函敎ͼ该参数是q个class的一个对象,q个函数的功能是被传入的对象(objectQ的所有非静态(non-staticQ成员变量的值都复制l自w这个object?/p> <code> <pre> CExample::CExample (const CExample& rv) {<br> a=rv.a; b=rv.b; c=rv.c;<br> }<br> </pre> </li> </ul> <p><strong class=important>必须注意Q?/strong>q两个默认构造函敎ͼempty construction ?copy constructor Q?/p> <p>只有在没有其它构造函数被明确定义的情况下才存在?/p> <p>如果M其它有Q意参数的构造函数被定义了,q两个构造函数就都不存在了?/p> <p>在这U情况下Q?/p> <p>如果你想要有empty construction ?copy constructor Q?/p> <p>必需要自己定义它们?/p> </code></code> <img src ="http://m.shnenglu.com/smallfa/aggbug/68576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-12-04 18:04 <a href="http://m.shnenglu.com/smallfa/archive/2008/12/04/68576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C在struct里面可以用public、privateQ默认的是publicQ而C++默认是private?/title><link>http://m.shnenglu.com/smallfa/archive/2008/12/04/68575.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Thu, 04 Dec 2008 10:01:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/12/04/68575.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/68575.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/12/04/68575.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/68575.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/68575.html</trackback:ping><description><![CDATA[C在struct里面可以用public、privateQ默认的是publicQ而C++默认是private?br><br>C在struct里面可以用public、privateQ默认的是publicQ而C++默认是private? <img src ="http://m.shnenglu.com/smallfa/aggbug/68575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-12-04 18:01 <a href="http://m.shnenglu.com/smallfa/archive/2008/12/04/68575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>法http://m.shnenglu.com/smallfa/archive/2008/11/27/67995.htmlhenry08henry08Thu, 27 Nov 2008 08:31:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/11/27/67995.htmlhttp://m.shnenglu.com/smallfa/comments/67995.htmlhttp://m.shnenglu.com/smallfa/archive/2008/11/27/67995.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/67995.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/67995.html{
    long a1 = 34, a2 = 23, a3 = 12;
    if( a1 > a2 )
    {
        long temp = a1;
        a1 = a2;
        a2 = temp;
    }
    if( a1 > a3 )
    {
        long temp = a1;
        a1 = a3;
        a3 = temp;
    }
    if( a2 > a3 )
    {
        long temp = a2;
        a2 = a3;
        a3 = temp;
    }
}
上面在每个if后面的复合语句中定义了一个时变量temp以借助~译器的静态分配内存功能来提供临时存放卡片的内存。上面的元素交换q没有按照前面所说映成函数Q是因ؓ在这里其只有三条语句且容易理解。如果要交换操作定义ؓ一函数
如果要将交换操作定义Z函数Q则应如下:
void Swap( long *p1, long *p2 )             void Swap( long &r1, long &r2 )
{                                           {
    long temp = *p1;                            long temp = r1;
    *p1 = *p2;                                  r1 = r2;
    *p2 = temp;                                 r2 = temp;
}                                           }
void main()                                 void main()
{                                           {
    long a1 = 34, a2 = 23, a3 = 12;             long a1 = 34, a2 = 23, a3 = 12;
    if( a1 > a2 )                               if( a1 > a2 )
        Swap( &a1, &a2 );                           Swap( a1, a2 );
    if( a1 > a3 )                               if( a1 > a3 )
        Swap( &a1, &a3 );                           Swap( a1, a3 );
    if( a2 > a3 )                               if( a2 > a3 )
        Swap( &a2, &a3 );                           Swap( a2, a3 );
}                                           }
    先看左侧的程序。上面定义了函数来表C给定盒子之间的交换操作Q注意参数类型用了long*Q这里指针表C引用(应注意指针不仅可以表C引用,q可有其它的语义Q以后会提到Q?br>


下面看右侧的E序。参数类型变成long&Q和指针一P依旧表示引用Q但注意它们的不同。后者表C它是一个别名,卛_是一个映,映射的地址是记录作为参数的数字的地址Q也是说它要求调用此函数时Q给出的作ؓ参数的数字一定是有地址的数?br>

henry08 2008-11-27 16:31 发表评论
]]>
函数http://m.shnenglu.com/smallfa/archive/2008/11/26/67941.htmlhenry08henry08Wed, 26 Nov 2008 15:46:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/11/26/67941.htmlhttp://m.shnenglu.com/smallfa/comments/67941.htmlhttp://m.shnenglu.com/smallfa/archive/2008/11/26/67941.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/67941.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/67941.html上面的返回类型ؓvoidQ前面提q,void是C++提供的一U特D数字类型,其仅仅只是ؓ了保障语法的严密性而已Q即M函数执行后都要返回一个数字(后面说明)Q而对于不用返回数字的函数Q则可以定义q回cd为voidQ这样就可以保证语法的严密性?/p>

可以认ؓ函数cd的地址cd的数字编译器会隐式{换成指针cd的数?/p>


重蝲函数表示函数名字一P但参数类型及个数不同的多个函?/p>

 声明是告诉编译器一些信息,以协助编译器q行语法分析Q避免编译器报错。而定义是告诉~译器生成一些代码,q且q些代码由q接器用?/p>

extern long a, *pA, &ra;
    上面声明(不是定义Q了三个变量a、pA和ra?br>因ؓextern表示外部的意思,因此上面p认ؓ是告诉编译器有三个外部的变量Qؓa、pA和raQ故被认为是声明语句Q所以上面将不分配Q何内存?br>同样Q对于函敎ͼ它也是一LQ?br>    extern void ABC( long );  ?nbsp; extern long AB( short b );



henry08 2008-11-26 23:46 发表评论
]]>
cd修饰W(type-specifierQ?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/26/67913.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Wed, 26 Nov 2008 07:52:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/26/67913.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67913.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/26/67913.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67913.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67913.html</trackback:ping><description><![CDATA[数组和指针都是类型修饰符Q之前提q的引用变量?#8220;&”也是cd修饰W?br><br><strong>指针修饰W?#8220;*”</strong>——其L接在变量名的前面Q表C当前类型ؓ原类型的指针。故Q?br>short a = 10, *pA = &a, **ppA = &pA;<br><br><strong> 引用修饰W?#8220;&”</strong>——其L接在变量名的前面Q表C此变量不用分配内存以和其绑定,而在说明cdӞ则不能有它,下面说明。由于表C相应变量不用分配内存以生成映射Q故其不像上qCU类型修饰符Q可以多ơ重复书写,因ؓ没有意义<br> <img src ="http://m.shnenglu.com/smallfa/aggbug/67913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-26 15:52 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/26/67913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在堆上分配内?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/26/67911.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Wed, 26 Nov 2008 07:40:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/26/67911.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67911.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/26/67911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67911.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67911.html</trackback:ping><description><![CDATA[unsigned long *pA = new unsigned long; *pA = 10;<br>unsigned long *pB = new unsigned long[ *pA ];<br><br>上面q请了两块内存QpA所指的内存Q即pA的值所对应的内存)?字节大小Q而pB所指的内存?*10=40字节大小。应该注意,׃new是一个操作符Q其l构为new <cd?gt;[<整型数字>]。它q回指针cd的数字,其中?lt;cd?gt;指明了什么样的指针类型,而后面方括号的作用和定义数组时一P用于指明元素的个敎ͼ但其q回的ƈ不是数组cdQ而是指针cd?br><br><br><br>delete pA; delete[] pB;<br><br>    注意delete操作Wƈ不返回Q何数字,但是其仍被称作操作符Q看h它应该被叫做语句更加合适,但ؓ了满_依旧是操作符的特性,C++提供了一U很Ҏ的数字类型——void。其表示无,即什么都不是Q这在《C++从零开始(七)》中详l说明。因此delete其实是要q回数字的,只不q返回的数字cd为void|了?br><br>    注意上面对pA和pB的释放不同,因ؓpA按照最开始的书写Q是new unsigned longq回的,而pB是new unsigned long[ *pA ]q回的。所以需要在释放pB时在delete的后面加?#8220;[]”以表C释攄是数l,不过在VC中,不管前者还是后者,都能正确释放内存Q无需“[]”的介入以帮助~译器来正确释放内存Q因ZWindows为^台而开发程序的VC是按照Windows操作pȝ的方式来q行内存分配的,而Windows操作pȝ在释攑ֆ存时Q无需知道Ʋ释攄内存块的长度Q因为其已经在内部记录下来(q种说法q不准确Q实际应是Cq行时期库干了这些事Q但其又是依赖于操作pȝ来干的,卛_实是有两层对内存理的包装,在此不表Q?br> <img src ="http://m.shnenglu.com/smallfa/aggbug/67911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-26 15:40 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/26/67911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>指针http://m.shnenglu.com/smallfa/archive/2008/11/26/67909.htmlhenry08henry08Wed, 26 Nov 2008 07:39:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/11/26/67909.htmlhttp://m.shnenglu.com/smallfa/comments/67909.htmlhttp://m.shnenglu.com/smallfa/archive/2008/11/26/67909.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/67909.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/67909.html再来看取内容操作W?#8220;*”Q其x的数字类型是指针cd或数l类型,它的计算是此指针cd的数字直接{换成地址cd的数?br>因ؓ指针cd的数字和地址cd的数字在数g是相同的Q仅仅计规则不?/p>


地址cd的数字是在编译时期给~译器用?br>指针cd的数字是在运行时期给代码用的



henry08 2008-11-26 15:39 发表评论
]]>
甌内存 静态分配动态分?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/26/67908.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Wed, 26 Nov 2008 07:38:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/26/67908.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67908.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/26/67908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67908.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67908.html</trackback:ping><description><![CDATA[<p>在申请内存时L甌固定大小的内存,则称此内存是静态分配的。前面提出的定义变量Ӟ~译器帮我们从栈上分配的内存属于静态分?/p> <p><br>Ҏ用户输入的不同而可能申请不同大的内存Ӟ则称此内存是动态分配的Q后面说的从堆上分配属于动态分配?/p> <p><br>同样Q静态分配的内存利用率不高或q用不够灉|Q但代码Ҏ~写且运行速度较快Q动态分配的内存利用率高Q不q编写代码时要复杂些Q需自己处理内存的管理(分配和释放)且由于这U管理的介入而运行速度较慢q代码长度增加?br>静态和动态的意义不仅仅如此,其有很多的深化,如硬~码和Y~码、紧耦合和松耦合Q都是静态和动态的深化?br></p> <img src ="http://m.shnenglu.com/smallfa/aggbug/67908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-26 15:38 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/26/67908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符?http://m.shnenglu.com/smallfa/archive/2008/11/26/67907.htmlhenry08henry08Wed, 26 Nov 2008 07:37:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/11/26/67907.htmlhttp://m.shnenglu.com/smallfa/comments/67907.htmlhttp://m.shnenglu.com/smallfa/archive/2008/11/26/67907.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/67907.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/67907.html charcdq行表示的字W串UCؓ单字节字W串QSingleByteQ,用这U表C方式记录的文本文gUCؓ是ANSI格式?br>

  多字节字W串QMultiByteQ,用这U表C方式记录的文本文gUCؓ是MBCS格式?br>

 宽字节字W串QWideCharQ,用这U表C方式记录的文本文gUCؓ是Unicode格式?br>         (一个shortcd的数字来表示Q即每个字符的长度固定ؓ2字节)



henry08 2008-11-26 15:37 发表评论
]]>
在线C++~译器介l?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/26/67894.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Wed, 26 Nov 2008 04:35:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/26/67894.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67894.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/26/67894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67894.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67894.html</trackback:ping><description><![CDATA[<p>下面的网址是最有名的两个在UC++~译|站Q?/p> <p><a >http://www.dinkumware.com/exam/default.aspx</a> <br><a >http://www.comeaucomputing.com/tryitout/</a><br>许多在线判题pȝ也可以用来进行在U编译:</p> <p><a >http://acm.zju.edu.cn/</a> <br><a >http://acm.pku.edu.cn/JudgeOnline/</a> <br><a >http://acm.uva.es/</a><br>你可能会好奇q些|站使用的编译器的版本和~译参数到底是什么。有些网站会提供q些信息Q而有些则不会。那么你只能靠自己d现这?#8220;U密”了?/p> <p>工欲善其事,必先利其器。让我们先看看一些从~译器获取信息的技巧?/p> <p>1. 输出?br>在C++中, 字符串常C能作为模板参数。大多数~译器会在错误信息中同时输出字符串的内容。下面的代码展示了这一技巧?</p> <p>template<const char *> class A {};<br>#define F0(x) #x<br>#define F1(x) F0(x)<br>#define V1 F1(__GNUC__)<br>int main()<br>{<br>    A<V1> a1;<br>}</p> <p><br>q里Q宏F0和F1用于整型{换成字符丌Ӏ编译器会输出类g"literal "3" is not a valid template argument because it is the address of an object with static linkage"的出错信息。里面的"3"是你想知道的宏的内宏V?</p> <p>2. 输出常数<br>同样QQҎ是不能作为模板参数的。编译器通常会在错误信息中包含QҎ的倹{利用这一点,我们可以输出点常数。不q很不幸的是QVC会隐式的Q点类型的模板参数转换成intQ参?a >https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296008</a>Q?br>下面是一U输出整型常量的ҎQ?</p> <p>template<int N><br>class A<br>{<br>private:<br>    A();<br>};<br>int main()<br>{<br>    A<sizeof(char)> a;<br>}</p> <p><br>3. 输出变量cd<br>有时候,你可能需要知道某些变量的实际cdQ这时候你可以使用下面的代码: </p> <p>struct Dummy {};<br>void Fun(const Dummy &);<br>int main()<br>{<br>    Fun(1+1U);<br>}</p> <p><br>PSQ如果你使用的是gccQ那么它会输?not convert `2' to `const Dummy&'"Q所以你需要将Fun的声明改?template<typename T> void Fun(T);"Q换句话_在gcc中上面的代码也可以用于输出常数的| </p> <p>4. 输出包含路径<br>如果要获取STL头文件的路径Q你可以使用Q?</p> <p>#include <ext/hash_set><br>using __gnu_cxx::hash_set; </p> <p>int main()<br>{<br>    hash_set<> m;<br>}</p> <p> </p> <p>PSQ这里也可以使用vector?</p> <p>好,现在是时候牛刀试了。关于如何获取编译器的版本信息,可以参考这文章:Pre-defined Compiler Macros</p> <p>下面是利用上面介l的技巧获得的dinkumware|站的一些资料: </p> <p>1. VC <br>版本 (_MSC_FULL_VER)Q?br>         VC8 140050727 <br>         VC7.1 13103077 <br>         VC7 13009466 <br>         VC6 12008804 <br>包含路径Q?<br>         D:\cplt501_vc_source\include (with _CPPLIB_VER=501) </p> <p>2. EDG<br>版本(__EDG_VERSION__):<br>         3.05  <br>~译参数Q?br>         edgcc --alt -D_WIN32 -D_M_IX86 --no_inlining --diag_suppress=1290 --long_long --wchar_t_keyword -D_C99 -ID:\cplt501_gen_source/include/c -ID:\cplt501_gen_source/include -IC:\PROGRA~1\MICROS~2.NET\VC7/include --exceptions --microsoft -c sourceFile.cpp <br>因ؓ使用了VC兼容模式q行~译Q所以编译器可能会模拟VC的部分bug </p> <p>3. GCC<br>版本Q?br>         3.2.0 <br>包含路径Q?br>         D:/cplt501_gen_source/include and D:/Mingw/include/c++/3.2/<br>可以看到q里使用的GCC的版本已l相当陈旧了</p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p><br>文章出处Q?a >http://www.diybl.com/course/3_program/c++/cppsl/2008108/149011.html</a></p> <img src ="http://m.shnenglu.com/smallfa/aggbug/67894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-26 12:35 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/26/67894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>赋D?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/26/67857.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Tue, 25 Nov 2008 16:18:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/26/67857.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67857.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/26/67857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67857.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67857.html</trackback:ping><description><![CDATA[<p>赋D?br>因此应在变量定义的时候就q行赋|但是会有性能上的影响Q不q很)Q以初始化变量而防止出现莫名其妙的?在表辑ּ中运用赋D符是不好的Q即使它可能让你写出看v来简l的语句Q但它也使代码的可维护性降低?/p> <p><br>true 0<br>false ?</p> <img src ="http://m.shnenglu.com/smallfa/aggbug/67857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-26 00:18 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/26/67857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>栈(StackQ? 堆(HeapQ?/title><link>http://m.shnenglu.com/smallfa/archive/2008/11/24/67743.html</link><dc:creator>henry08</dc:creator><author>henry08</author><pubDate>Mon, 24 Nov 2008 10:45:00 GMT</pubDate><guid>http://m.shnenglu.com/smallfa/archive/2008/11/24/67743.html</guid><wfw:comment>http://m.shnenglu.com/smallfa/comments/67743.html</wfw:comment><comments>http://m.shnenglu.com/smallfa/archive/2008/11/24/67743.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.shnenglu.com/smallfa/comments/commentRss/67743.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/smallfa/services/trackbacks/67743.html</trackback:ping><description><![CDATA[<br><span style="COLOR: #0000ff">C++卛_许程序员有两U向操作pȝ甌内存的方式?br></span>    前一U就是在栈上分配Q申L内存大小<span style="COLOR: #ff0000">固定不变</span>?br>    后一U是在堆上分配,<span style="COLOR: #ff0000">甌的内存大可以在q行的时候变?/span>Q不是固定不变的<br>_______+++++++++++++++++++++++++++++++++++_____________________________<br><br><br><br><br><strong>栈(StackQ?br></strong>                    <br>                  : ME序执行前,<span style="COLOR: red">预先分配</span>一固定长度的内存空_<br>                    q块内存I间被称作栈,也被叫做堆栈<br>                    即程序员自己判断可以使用哪些内存Q?br>                    ?span style="COLOR: red">不是</span>操作pȝ,很明显,<br>                   上面的工作是<span style="COLOR: red">q译器来做</span>的,   <br>                   工作只是从操作系l变到程序自p已,<br><span style="COLOR: red">                   好处</span>是׃E序一开始执行时已l分配了一大块q箋内存,<br><span style="COLOR: red">                   坏处</span>也就是只能在~译时期分配内存<br><br><br><span style="COLOR: #0000ff">上面的工作是~译器做的,即程序员q不参与堆栈的维护。但上面已经说了Q堆栈相当于在编译时期分配内存,因此一旦计好某块内存的偏U,则这块内存就只能那么大,不能变化?br><br><br>__________________________________________________________________________________________________<br><br><font color=#000000><strong>堆(HeapQ?br><br>                 </strong>在Windows操作pȝ下,?span style="COLOR: #ff0000">操作pȝ分配的内存就叫做?/span>Q?br>                 而栈可以认ؓ是在E序开始时分配的?br>                 因此在堆上就可以分配大小变化的内存块Q?br>                 因ؓ?span style="COLOR: #ff0000">q行时期</span>x分配的内存,<br>                ?span style="COLOR: #ff0000">不是~译时期</span>已计好大小的内存块?br></font></span> <img src ="http://m.shnenglu.com/smallfa/aggbug/67743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/smallfa/" target="_blank">henry08</a> 2008-11-24 18:45 <a href="http://m.shnenglu.com/smallfa/archive/2008/11/24/67743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++ 开blogshttp://m.shnenglu.com/smallfa/archive/2008/11/11/66606.htmlhenry08henry08Tue, 11 Nov 2008 07:35:00 GMThttp://m.shnenglu.com/smallfa/archive/2008/11/11/66606.htmlhttp://m.shnenglu.com/smallfa/comments/66606.htmlhttp://m.shnenglu.com/smallfa/archive/2008/11/11/66606.html#Feedback0http://m.shnenglu.com/smallfa/comments/commentRss/66606.htmlhttp://m.shnenglu.com/smallfa/services/trackbacks/66606.html

henry08 2008-11-11 15:35 发表评论
]]>
ŷƷۺϾþ| ƷۺϾþþþþ97| þþƷˬӰ| ƷƵþþ| ҹƵþþþһ | ۺɫ77777þ| ƷŮٸaѾþ| Բľþþþþ| þۺ϶| Ժձһձþ| һƷ˾þ | ٸƷþþһ | ˾Ʒþ޸岻| þþþù| ƷþþþjkƷ| ھƷþþþþþ| þþƷһ99| ޹˾þþƷ99| ƷþëƬ| ޾Ʒ99þ| AVɫۺϾþAVɫۺ | þþ뾫ƷպĦ| þþƷ| ۿƷþ| ĻۺϾþ| þþþþAv뾫Ʒר| ɫþùƷ12p | ݺݾƷþþĻ| þþþþþƷþþþ| þsmȤ| þþþAVרɫ| 99þù¶Ʒ| þۺɫ| þþþ?V| XxŷʸƷþþþþ| 91ƷɫۺϾþ| ٸ߳ҽоþþþþ| ŷҹƷþþþ | Ⱦþվȡ| þþþþAŷAV| þ996ȾƷxxxx|