??xml version="1.0" encoding="utf-8" standalone="yes"?>99久久精品国产高清一区二区,99re这里只有精品热久久,久久午夜无码鲁丝片午夜精品http://www.shnenglu.com/LittleStar/ O(∩_?O 月亮的fans ^_^zh-cnWed, 07 May 2025 02:16:21 GMTWed, 07 May 2025 02:16:21 GMT60【{】多?Polymorphism)的实现机??Q-C++?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99063.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Tue, 20 Oct 2009 13:36:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99063.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/99063.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99063.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/99063.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/99063.html</trackback:ping><description><![CDATA[<p>多?Polymorphism)是面向对象的核心(j)概念Q本文以C++ZQ讨论多态的具体实现。C++中多态可以分为基于承和虚函数的动态多态以?qing)基于模板的静(rn)态多态,如果没有特别指明Q本文中出现的多态都是指前者,也就是基于承和虚函数的动态多态。至于什么是多态,在面向对象中如何使用多态,使用多态的好处{等问题Q如果大家感兴趣的话Q可以找本面向对象的书来看看?br>    Z(jin)方便说明Q下面D一个简单的使用多态的例子(From [1] )Q?/p> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Shape<br>{<br>protected:<br>  int m_x;    // X coordinate<br>  int m_y;  // Y coordinate<br>public:<br>  // Pure virtual function for drawing<br>  virtual void Draw() = 0;  <br><br>  // A regular virtual function<br>  virtual void MoveTo(int newX, int newY);<br><br> // Regular method, not overridable.<br>  void Erase();<br><br>  // Constructor for Shape<br>  Shape(int x, int y); <br><br> // Virtual destructor for Shape<br>  virtual ~Shape();<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">// Circle class declaration<br>class Circle : public Shape<br>{<br>private:<br>   int m_radius;    // Radius of the circle <br>public:<br>   // Override to draw a circle<br>   virtual void Draw();    <br><br>   // Constructor for Circle<br>   Circle(int x, int y, int radius);<br><br>  // Destructor for Circle<br>   virtual ~Circle();<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">// Shape constructor implementation<br>Shape::Shape(int x, int y)<br>{<br>   m_x = x;<br>   m_y = y;<br>}<br>// Shape destructor implementation<br>Shape::~Shape()<br>{<br>//...<br>}</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"> // Circle constructor implementation<br>Circle::Circle(int x, int y, int radius) : Shape (x, y)<br>{<br>   m_radius = radius;<br>}<br><br>// Circle destructor implementation<br>Circle::~Circle()<br>{<br>//...<br>}<br><br>// Circle override of the pure virtual Draw method.<br>void Circle::Draw()<br>{<br>   glib_draw_circle(m_x, m_y, m_radius);<br>}</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><br>main()<br>{<br>  // Define a circle with a center at (50,100) and a radius of 25<br>  Shape *pShape = new Circle(50, 100, 25);<br><br>  // Define a circle with a center at (5,5) and a radius of 2<br>  Circle aCircle(5,5, 2);<br><br>  // Various operations on a Circle via a Shape pointer<br><strong>  //</strong>Polymorphism<br><strong>  pShape->Draw();</strong><br><strong>  pShape->MoveTo(100, 100);<br><br></strong>  pShape->Erase();<br>  delete pShape;<br><br> // Invoking the Draw method directly<br>  aCircle.Draw();<br>}    </div> <p>     例子中用到多态的代码以黑体标Z(jin)Q它们一个很明显的特征就是通过一个基cȝ指针Q或者引用)(j)来调用不同子cȝҎ(gu)?br>     那么Q现在的问题是,q个功能是怎样实现的呢Q我们可以先来大概猜一下:(x)对于一般的Ҏ(gu)调用Q到?jin)汇~代码这一层次的时候,一般都是?Call funcaddr q样的指令进行调用,其中funcaddr是要调用函数的地址。按理来_(d)当我使用指针pShape来调用Draw的时候,~译器应该将Shape::Draw的地址赋给funcaddrQ然后Call 指o(h)可以直接调用Shape::Draw?jin),q就跟用pShape来调用Shape::Erase一栗但是,q行l果却告诉我们,~译器赋lfuncaddr的值却是Circle::Drawde的倹{这p明,~译器在对待DrawҎ(gu)和EraseҎ(gu)时用了(jin)双重标准。那么究竟是谁有q么大的法力Qɾ~译器这个铁面无U的判官都要另眼相看呢?<strong>virtualQ!<br>     </strong>CleverQ!正是virtualq个关键字一手导演了(jin)q一?#8220;乑֝大挪U?#8221;的好戏。说道这里,我们先要明确两个概念Q静(rn)态绑定和动态绑定?br>    1、静(rn)态绑定(static bingdingQ,也叫早期l定Q简单来说就是编译器在编译期间就明确知道所要调用的Ҏ(gu)Qƈ该Ҏ(gu)的地址赋给?jin)Call指o(h)的funcaddr。因此,q行期间直接使用Call指o(h)可调用到相应的Ҏ(gu)?br>    2、动态绑定(dynamic bindingQ,也叫晚期l定Q与?rn)态绑定不同,在编译期_(d)~译器ƈ不能明确知道I竟要调用的是哪一个方法,而这Q要知道q行期间使用的具体是哪个对象才能军_?br>    好了(jin)Q有?jin)这两个概念以后Q我们就可以_(d)virtual的作用就是告诉编译器Q我要进行动态绑定!~译器当然会(x)重你的意见Q而且Z(jin)完成你这个要求,~译器还要做很多的事情:(x)~译器自动在声明?jin)virtualҎ(gu)的类中插入一个指针vptr和一个数据结构VTableQvptr用以指向VTableQVTable是一个指针数l,里面存放着函数的地址Q,q保证二者遵守下面的规则Q?br>    1、VTable中只能存攑֣明ؓ(f)virtual的方法,其它Ҏ(gu)不能存放在里面。在上面的例子中QShape的VTable中就只有DrawQMoveTo和~Shape。方法Erase的地址q不能存攑֜VTable中。此外,如果Ҏ(gu)是纯虚函敎ͼ? DrawQ那么同栯在VTable中保留相应的位置Q但是由于纯虚函数没有函CQ因此该位置中ƈ不存放Draw的地址Q而是可以选择存放一个出错处理的函数的地址Q当该位|被意外调用Ӟ可以用出错函数进行相应的处理?br>    2、派生类的VTalbe中记录的从基cMl承下来的虚函数地址的烦(ch)引号必须跟该虚函数在基类VTable中的索引号保持一致。如在上例中Q如果在Shape的VTalbe中,Draw? 1 P MoveTo 2 P~Shape?3 P那么Q不这些方法在Circle中是按照什么顺序定义的QCircle的VTable中都必须保证Draw? 1 PMoveTo?2受至?3Pq里是~Circle。ؓ(f)什么不是~Shape啊?嘿嘿Q忘啦,析构函数不会(x)l承的?br>    3、vptr是由~译器自动插入生成的Q因此编译器必须负责为其q行初始化。初始化的时间选在对象创徏Ӟ而地点就在构造函C。因此,~译器必M证每个类臛_有一个构造函敎ͼ若没有,自动为其生成一个默认构造函数?br>     4、vptr通常攑֜对象的v始处Q也是Addr(obj) == Addr(obj.vptr)?br>    你看Q天下果然没有免费的午餐Qؓ(f)?jin)实现动态绑定,~译器要为我们默默干?jin)这么多的脏话篏zR如果你想体验一下编译器的辛劻I那么可以试用C语言模拟一下上面的行ؓ(f)Q?】中有q么一个例子。好?jin),现在万事具备Q只Ơ东风了(jin)。编译,q接Q蝲入,GOQ当E序执行? <strong>pShape->Draw()</strong>的时候,上面的设施也开始v作用?jin)。?br>    前面已经提到Q晚期绑定时之所以不能确定调用哪个函敎ͼ是因为具体的对象不确定。好?jin),当运行?strong>pShape->Draw()</strong>Ӟ对象出来?jin),它由pShape指针标出。我们找到这个对象后Q就可以扑ֈ它里面的vptrQ在对象的v始处Q,有了(jin)vptr后,我们找C(jin)VTableQ调用的函数在眼前?jin)。。等{,VTable中方法那么多Q我I竟使用哪个呢?不用着急,~译器早已ؓ(f)我们做好?jin)记录?x)~译器在创徏VTableӞ已经为每个virtual函数安排好了(jin)座次Qƈ且把q个索引可录了(jin)下来。因此,当编译器解析?strong>pShape->Draw()</strong>的时候,它已l?zhn)?zhn)的函数的名字用烦(ch)引号来代替了(jin)。这时候,我们通过q个索引号就可以在VTable中得C个函数地址QCall itQ?br>    在这里,我们׃?x)到Z么会(x)有第二条规定?jin),通常Q我们都是用基类的指针来引用zcȝ对象Q但是不具体对象是哪个zcȝQ我们都可以使用相同的烦(ch)引号来取得对应的函数实现?br>     现实中有一个例子其实跟q个蛮像的:(x)报警?sh)话?10Q?19Q?20QVTable中不同的Ҏ(gu)Q。不同地方的人拨打不同的L(fng)所产生的结果都是不一L(fng)。譬如,在三环外的一个hQ具体对象)(j)跟一环内的一个hQ另外一个具体对象)(j)?19Q最后调用的消防队肯定是不一L(fng)Q这是多态了(jin)。这是怎么实现的呢Q每个h都知道一个报警中?j)(VTableQ里面有三个Ҏ(gu) 110Q?19Q?20Q。如果三环外的一个h需要火警抢险(一个具体对象)(j)Ӟ它就拨打119Q但是他肯定不知道最后是哪一个消防队?x)出现的。这得有报警中心(j)来决定,报警中心(j)通过q个具体对象Q例子中是具体位置?jin)?j)以及(qing)他说拨打的电(sh)话号码(可以理解成烦(ch)引号Q,报警中心(j)可以定应该调度哪一个消防队q行抢险Q不同的动作Q?br>     q样Q通过vptr和VTable的帮助,我们实C(jin)C++的动态绑定。当?dng)q仅仅是单承时的情况,多重l承的处理要相对复杂一点,下面要说一下最单的多重l承的情况,至于虚承的情况Q有兴趣的朋友可以看? Lippman的《Inside the C++ Object Model》,q里暂时׃展开?jin)。(主要是自p没搞清楚Q况且现在多重扉K不怎么使用?jin),虚承应用的Z(x)更了(jin)Q?br>     首先Q我要先说一下多重承下对象的内存布局Q也是说该对象是如何存放本w的数据的?/p> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Cute<br>{<br>public:<br> int i;<br> virtual void cute(){ cout<<"Cute cute"<<endl; }<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Pet<br>{<br>public:<br>   int j;<br>   virtual void say(){ cout<<"Pet say"<<endl;  }<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Dog : public Cute,public Pet<br>{<br>public:<br> int z;<br> void cute(){ cout<<"Dog cute"<<endl; }<br> void say(){ cout<<"Dog say"<<endl;  }<br>};</div> <p>    在上面这个例子中Q一个Dog对象在内存中的布局如下所C:(x)                    </p> <p> <table style="border: medium none ; border-collapse: collapse;" class="MsoTableGrid" border="1" cellpadding="0" cellspacing="0"> <tbody> <tr> <td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 59.4pt;" width="79"> <p style="margin: 0cm 0cm 0pt; text-align: center;" class="MsoNormal" align="center"><strong><span lang="en">Dog</span></strong></p> </td> </tr> <tr> <td style="border-style: none solid solid; border-color: #ece9d8 windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; background-color: transparent; width: 59.4pt;" width="79" valign="top"> <p style="margin: 0cm 0cm 0pt;" class="MsoNormal"><span lang="en">Vptr1</span></p> </td> </tr> <tr> <td style="border-style: none solid solid; border-color: #ece9d8 windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; background-color: transparent; width: 59.4pt;" width="79" valign="top"> <p style="margin: 0cm 0cm 0pt;" class="MsoNormal"><span lang="en">Cute::i</span></p> </td> </tr> <tr> <td style="border-style: none solid solid; border-color: #ece9d8 windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; background-color: transparent; width: 59.4pt;" width="79" valign="top"> <p style="margin: 0cm 0cm 0pt;" class="MsoNormal"><span lang="en">Vptr2</span></p> </td> </tr> <tr> <td style="border-style: none solid solid; border-color: #ece9d8 windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; background-color: transparent; width: 59.4pt;" width="79" valign="top"> <p style="margin: 0cm 0cm 0pt;" class="MsoNormal"><span lang="en">Pet::j</span></p> </td> </tr> <tr> <td style="border-style: none solid solid; border-color: #ece9d8 windowtext windowtext; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; background-color: transparent; width: 59.4pt;" width="79" valign="top"> <p style="margin: 0cm 0cm 0pt;" class="MsoNormal"><span lang="en">Dog::z</span></p> </td> </tr> </tbody> </table> <br>     也就是说Q在Dog对象中,?x)存在两个vptr,每一个跟所l承的父cȝ对应。如果我们要惛_现多态,必d对象中准地扑ֈ相应的vptrQ以调用不同的方法。但是,如果Ҏ(gu)单承时的逻辑Q也是vptr攑֜指针指向位置的v始处Q那么,要在多重l承情况下实玎ͼ我们必须保证在将一个派生类的指针隐式或者显式地转换成一个父cȝ指针Ӟ得到的结果指向相应派生类数据在Dog对象中的起始位置。幸好,q工作编译器已经帮我们完成了(jin)。上面的例子中,如果Dog向上转换成Pet的话Q编译器?x)自动计Pet数据在Dog对象中的偏移量,该偏U量加上Dog对象的v始位|,是Pet数据的实际地址?jin)?/p> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">int main()<br>{<br> Dog* d = new Dog();<br> cout<<"Dog object addr : "<<d<<endl;<br> Cute* c = d;<br> cout<<"Cute type addr : "<<c<<endl;<br> Pet* p = d;<br> cout<<"Pet type addr : "<<p<<endl;<br> delete d;<br>}<br></div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">output:<br>Dog object addr : 0x3d24b0<br>Cute type addr : 0x3d24b0<br>Pet type addr : 0x3d24b8   // 正好指向Dog对象的vptr2处,也就是Pet的数?br></div> <p>      好了(jin)Q既然编译器帮我们自动完成了(jin)不同父类的地址转换Q我们调用虚函数的过E也p单承统一h?jin)?x)通过具体对象Q找到vptrQ通常指针的v始位|,因此Cute扑ֈ的是vptr1Q而Pet扑ֈ的是vptr2Q,通过vptrQ我们找到VTableQ然后根据编译时得到的VTable索引P我们取得相应的函数地址Q接着可以马上调用了(jin)?br><br>      在这里,Z也提一下两个特D的Ҏ(gu)在多态中的特别之处吧Q第一个是构造函敎ͼ在构造函C调用虚函数是不会(x)有多态行为的Q例子如下:(x)</p> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Pet<br>{<br>public:<br>   Pet(){ sayHello(); }<br>   void say(){ sayHello(); }<br><br>   virtual void sayHello()<br>   {<br>     cout<<"Pet sayHello"<<endl;<br>   }<br>   <br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Dog : public Pet<br>{<br>public:<br>   Dog(){};<br>   void sayHello()<br>   {<br>     cout<<"Dog sayHello"<<endl;<br>   }<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">int main()<br>{<br> Pet* p = new Dog();<br> p->sayHello();<br> delete p;<br>}</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">output:<br>Pet sayHello //直接调用的是Pet的sayHello()<br>Dog sayHello //多?br></div> <p>     W二个就是析构函敎ͼ使用多态的时候,我们l常使用基类的指针来引用zcȝ对象Q如果是动态创建的Q对象用完后,我们使用delete来释攑֯象。但是,如果我们不注意的话,?x)有意想不到的情况发生?/p> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Pet<br>{<br>public:<br>   ~Pet(){ cout<<"Pet destructor"<<endl;  }<br>  //virtual ~Pet(){ cout<<"Pet virtual destructor"<<endl;  }<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">class Dog : public Pet<br>{<br>public:<br>   ~Dog(){ cout<<"Dog destructor"<<endl;};<br>   //virtual ~Dog(){ cout<<"Dog virtual destructor"<<endl;  }<br>};</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">int main()<br>{<br> Pet* p = new Dog();<br> delete p;<br>}</div> <div style="border: 1px solid #cccccc; margin: 5px 20px; padding: 5px; background: #f3f3f3 none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">outputQ?br>Pet destructor  //p了(jin)QDog的析构函数没有调用,memory leak!<br><br>如果我们析构函数改成virtual以后Q结果如?br>Dog virtual destructor<br>Pet virtual destructor   // That's OK!</div> <p>    所以,如果一个类设计用来被承的话,那么它的析构函数应该被声明ؓ(f)virtual的?/p><img src ="http://www.shnenglu.com/LittleStar/aggbug/99063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-10-20 21:36 <a href="http://www.shnenglu.com/LittleStar/archive/2009/10/20/99063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{】不当用memset函数带来的麻?ch)问?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99061.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Tue, 20 Oct 2009 13:11:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99061.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/99061.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/10/20/99061.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/99061.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/99061.html</trackback:ping><description><![CDATA[通常在C的编E中Q我们经怋用memset函数一块连l的内存区域清零或设|ؓ(f)其它指定的|最q在UL一Djava代码到C++的时候,不当使用memset函数p?jin)我几个时的调试时间。对于虚函数的底层机制很?a style="font-size: 1em;" id="vad_3" class="vLink9999" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 3,'');}" title="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseoverwhileload =" false;="" hideto=" window.settimeout('checkifmouseoverlayer()',500);}" onclick="" target="_blank">资料</a>都有较详l?a style="font-size: 1em;" id="vad_1" class="vLink9999" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 1,'');}" title="iphone @utops.cc" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseoverwhileload =" false;="" hideto=" window.settimeout('checkifmouseoverlayer()',500);}" onclick="" target="_blank">阐述</a>Q但Ҏ(gu)个h而言Q这ơ的调试让我感触颇深? <br><br>先来看一D代码,在承的cAdvance之中Q有很多属性字D,?a style="font-size: 1em;" id="vad_0" class="vLink9999" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 0,'');}" title="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseoverwhileload =" false;="" hideto=" window.settimeout('checkifmouseoverlayer()',500);}" onclick="" target="_blank">希望</a>其清成0或NULLQ于是在构造函C我通过memset当前类的所有属性置0?<br><br>class Base{ <br><br>public: <br><br>virtual void kickoff() = 0; <br><br>}; <br>class Advance:public Base{ <br><br>public: <br><br>Advance(){ <br><br>memset(this, 0, sizeof(Advance)); <br><br>} <br><br>void kickoff(){ <br><br>count++; <br><br>//... do something else; <br><br>} <br><br>private: <br><br>int attr1, attr2; <br><br>char* label; <br><br>int count; <br><br>//... other attributes, they should be initiated to 0 or NULL at beginning. <br><br>}; <br><br>int _tmain(int argc, _TCHAR* argv[]) <br><br>{ <br>Base* ptr = new Advance(); <br>ptr->kickoff(); <br>return 0; <br>} <br><br>q样看似能正常运行,但运行程序时Q你?x)发现类g下面的错误:(x) <br><br>TestVirtual.exe 中的 0x00415390 处未处理的异? 0xC0000005: d位置 0x00000000 时发生访问冲H? <br><br>同时断点停留在ptr->kickoff()处,从错误提C我们可以得知无法调用kickoffҎ(gu)Q这个方法的指针没有被正初始化Q但Z么呢Q? <br><br>指出问题之前Q先看看q段文献上的关于虚函数机制的说明Q?<br><br>函数赖以生存的底层机Ӟ(x)vptr + vtable。虚函数的运行时实现采用?jin)VPTR/VTBL的Ş式,q项<a style="font-size: 1em;" id="vad_2" class="vLink9999" onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 2,'');}" title="%u7EC6%u6570%u7231%u4E0A%u53A8%u623F%u7684%u7406%u7531 @utops.cc" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseoverwhileload =" false;="" hideto=" window.settimeout('checkifmouseoverlayer()',500);}" onclick="" target="_blank">技?/a>的基Q? <br>①编译器在后Cؓ(f)每个包含虚函数的cM生一个静(rn)态函数指针数l(虚函数表Q,在这个类或者它的基cM定义的每一个虚函数都有一个相应的函数指针? <br>②每个包含虚函数的类的每一个实例包含一个不可见的数据成员vptrQ虚函数指针Q,q个指针被构造函数自动初始化Q指向类的vtblQ虚函数表)(j) <br>③当客户调用虚函数的时候,~译器生代码反指向到vptrQ烦(ch)引到vtbl中,然后在指定的位置上找到函数指针,q发?gu)用? <br><br>q里的问题,出?<br><br>memset(this, 0, sizeof(Advance)); <br><br>上面Q虚函数指针应该在进入构造函数赋g之前自动初始化的Q而memset却又已l初始化好的指针??jin),q就是ؓ(f)什么会(x)产生上面的访问零址的错误。将上面的memset语句去除E序可以正常运行了(jin)? <br><br>所以,从上面的问题中,我们可以看出在构造函C内调用memset整个对象清0是很有风险的Q当没有虚函数的时候上面程序可以正常运行(可以试着BasecȝU虚函数声明Ҏ(gu)非虚函数再运行程序)(j)。初始化cȝ属性对象时Q比较稳妥的办法q是手动逐个q行初?<img src ="http://www.shnenglu.com/LittleStar/aggbug/99061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-10-20 21:11 <a href="http://www.shnenglu.com/LittleStar/archive/2009/10/20/99061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shadow map 阴媄(jing)囄法的思?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98538.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Tue, 13 Oct 2009 15:34:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98538.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/98538.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98538.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/98538.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/98538.html</trackback:ping><description><![CDATA[<br><br><br>       shadow map 以前早就研究q,不过一ơ不心(j)把以前做的东襉K弄丢?jin),今天重新做?jin)一下,<br>加到?jin)系l里Q给大家看下效果Q)(j)<br><br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/shadowmap.JPG" width="640" height="480"><br><br>shadow map法原理很简?先简单介l下法l新人:(x)<br>1.以光源所在位|ؓ(f)观察Ҏ(gu)染场景(可以只渲染需要生阴q物体Q将渲染后的深度g存深度图Q一张事先准备好的纹理)(j)?br>在此步需要注意的?此次渲染用到的模型观视投q阵(以后UmvpQ需要保存一下,下一步要用到?br>2.正常渲染场景Q将点坐标乘以步骤一时候的mvpQ将坐标变换C光源察点的坐标系里,比较z值和从深度图中读出来?br>值得大小判断遮挡Q有遮挡的话输出颜色减弱或者换成别的随W你?jin)。其中有个地斚w要注意,如何从深度图U理中读数据Q?br>q个我是q么解决的:(x)float2 suv = ((spos.xy/spos.z))//其中spos是变换到光源坐标pM的顶Ҏ(gu)据,得到的suvl过处理后可?br>当做深度囄U理坐标|dҎ(gu)为float4 shadow = tex2D(t11,(suv+1.0)*0.5)Q其中用C个?1Q?】到?Q?】的变换?br>剩下的就是比较了(jin)  Q?<br>            float sz =  1 - spos.z/(gDepthSize)Q?/深度值变换到?Q?】区_(d)gDepthSize是获得深度纹理时渲染场景的最深?  <br>            //增加阴媄(jing)<br>            if((sz < shadow.x))//sz是就?br>            {<br>                color = color*(1 - shadow);<br>                color.w = 1.0;<br>                //color = float4(sz,sz,sz,1);<br>            }<br>//----------------------------------------------------------------------------------------------------------------------------<br>关于shadow map 法的缺?跟大家讨Z?<br>永远的困扰shadow map的失真问题,当光源照场景稍大的时候失真现象就?x)很严重Q有些改q算法,但都觉得L不治本?br>如果说我整个场景有很多到处跑的hQ那他们的阴影效果要怎样做呢Q?Q?br><br>感觉shadow map用在生成当前角色的阴影挺好,如果是大范围的不大适合。很多静(rn)态的物体可以先把阴媄(jing)事先计算好,用的时?br>直接dQ没有必要每帧都重新计算?br><br>//----------------------------------------------------------------------------------------------------------------------------<br>shadow map 最大的好处是可以处理透明U理的阴影,以ؓ(f)我的场景的树(wi)是用透明U理MȝQ如果得到的阴媄(jing)是个?br>形那很怪了(jin)Q幸好shadow map 没有q个问题Q!Q?br><br><br><br><img src ="http://www.shnenglu.com/LittleStar/aggbug/98538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-10-13 23:34 <a href="http://www.shnenglu.com/LittleStar/archive/2009/10/13/98538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vertex shader texture 讉KU理的方?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98452.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Tue, 13 Oct 2009 01:02:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98452.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/98452.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/10/13/98452.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/98452.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/98452.html</trackback:ping><description><![CDATA[<br><br>         今天考虑E序的优化问题,H然惛_说现在vetex shader已经可以讉KU理资源?jin),可以把访问高度图的操作{U?br>到vetex shader中去做计,GPU讉KU理的速度要比CPU讉K内存快多?jin)吧Q我是这么认为的Q。不q遇见一个问题?br>用tex2D讉K出来的值怪怪的Q不是我要的高度U理|后来发现如果fragment shader里面讉K?jin)别的纹理?x)影响到vetex?br>面的Q上|google?jin)一下,好多人都说得?tex2DLod才行Q试?jin)下一点好转的q象都没有,又有U理得是float的,参照<br>着改了(jin)下,q是不行。(很多时候在|上查到的都不好用,当然也有好用的,有点废话Q哈哈)(j)<br>        后来H然发现我的sampler都没有跟寄存器绑定,l定?jin)以后就好?jin)Q很奇怪,N说只调用cgGLSetTextureParameter<br>q不能实现纹理的l定Q?nbsp;  现在我把所有sampler都跟一个寄存器l定后就一切正怺(jin)?br><br>像q样Q?br>//--------------------------------------------------------------------------------<br>sampler2D t10 :TEXUNIT0;//地面高度?    其他的sampler也需要绑定到寄存器才?x)好?br><br>OutPut xS_v(float4 ipos:POSITION,<br>            float2 tex:TEXCOORD0,<br>            float3 normal:NORMAL)<br>{<br>    OutPut OUT;                            //out是关键字<br>    ipos.y =tex2D(t10,tex).z*256;<br>//---------------------------------------------------------------------------------<br><br><br>cg语言q行出来的结果经常怪怪的Q有一ơ我故意写错?jin)一句话Q结果编译也能通过Q只是显C出来的完全?br>是我惌的,有没有高人指点一下,多谢Q!<br><br><br>不过把访问高度图改到用GPU讉KU理后,效果q是很明昄Q速度提升?jin)差不多一倍?br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/gaileshude.JPG" width="647" height="487"><br><br><br><br> <img src ="http://www.shnenglu.com/LittleStar/aggbug/98452.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-10-13 09:02 <a href="http://www.shnenglu.com/LittleStar/archive/2009/10/13/98452.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>水面效果? 应用?jin)动态纹理,法线扰动Q反纹?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/10/12/98336.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Sun, 11 Oct 2009 16:48:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/10/12/98336.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/98336.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/10/12/98336.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/98336.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/98336.html</trackback:ping><description><![CDATA[<br>最q的工作Q?br><br>1.实现?jin)刀客的动作控制。(md2文gQGPU实现帧动画)(j)?br>2.试验?jin)水面效果(有反纹理映,水面法线贴图计算光照和扰动?j)?br>3.试验?jin)billboard效果?br>4.修改E序中的一些bug?br><br>有两个个问题Q?br>1.OpenGL如何提高效率Q欢q指教!<br>2.flt文g如何化,有好用的工具么,我的都是?dsD来的Q面数太多了(jin)Q不大适用?br><br>发几张孬图,ȝ大方Q?br><br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/shuimian.JPG" width="647" height="492"><br><br>感觉水面反射加了(jin)?wi)的倒媄(jing)反而变得怪怪的Q!<br><br>再来几张前几天截得图<br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/kongzhonghuayuan.JPG" width="644" height="487"><br><br>q是我的花园,大树(wi)的纹理烂透了(jin)?br><br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/xiaohe.JPG" width="642" height="487"><br><br><br>河水 哗啦?#8230;…<br><br><br><br><img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/meijiadimiande.JPG" width="647" height="487"><br><br>L地Ş的效果,感觉q蛮漂亮的,呵呵<br><br>大家有什么看法尽量留aQ?zhn)的关注就是对我最大的帮助Q!<br><br> <img src ="http://www.shnenglu.com/LittleStar/aggbug/98336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-10-12 00:48 <a href="http://www.shnenglu.com/LittleStar/archive/2009/10/12/98336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Parallax Mapping 效果?很烂的效果图 http://www.shnenglu.com/LittleStar/archive/2009/09/25/97192.htmlLittle StarLittle StarThu, 24 Sep 2009 19:33:00 GMThttp://www.shnenglu.com/LittleStar/archive/2009/09/25/97192.htmlhttp://www.shnenglu.com/LittleStar/comments/97192.htmlhttp://www.shnenglu.com/LittleStar/archive/2009/09/25/97192.html#Feedback2http://www.shnenglu.com/LittleStar/comments/commentRss/97192.htmlhttp://www.shnenglu.com/LittleStar/services/trackbacks/97192.htmlnormal map


Parallax Mapping



对应的网格图



着人少发两张等着挨砖头的效果图?br>
看了(jin)一天的资料Q证实了(jin)原来的想法是对的?br>normal map  ?bump map 的改q,主要是GPU可编Eؓ(f)其创造了(jin)条g?br>parallax map ?normal map 的改q版本,相当于是对normal map 的修正,没什么心(j)意?br>
Displacement Mapping貌似挺牛Q明天仔l研I下 Q?Q?br>

Little Star 2009-09-25 03:33 发表评论
]]>
Texture Blending && Phone Model && Roam Terrain Utilize the Cg to realizehttp://www.shnenglu.com/LittleStar/archive/2009/09/24/97084.htmlLittle StarLittle StarWed, 23 Sep 2009 18:09:00 GMThttp://www.shnenglu.com/LittleStar/archive/2009/09/24/97084.htmlhttp://www.shnenglu.com/LittleStar/comments/97084.htmlhttp://www.shnenglu.com/LittleStar/archive/2009/09/24/97084.html#Feedback3http://www.shnenglu.com/LittleStar/comments/commentRss/97084.htmlhttp://www.shnenglu.com/LittleStar/services/trackbacks/97084.html

先来张调整了(jin)参数的roam|格囄Q把面片数约束在1wQ这下roam的效果就明显?jin)吧Q?br>发现地势如果不是特别q_的话Q很难找C个满意的参数Q既能减面片数Q又能取得很好的昄效果?br>如果有大片大片的q_Q那q单了(jin)?br>


q是使用cg语言实现?texture blend 使用四张U理加一个细节纹理؜合而成Q?br>增加?jin)像素?Phone 光照模型。光照的颜色有点怪怪的?br>


Little Star 2009-09-24 02:09 发表评论
]]>
改进的roam terrain 效果?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/09/21/96813.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Sun, 20 Sep 2009 17:00:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/09/21/96813.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/96813.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/09/21/96813.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/96813.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/96813.html</trackback:ping><description><![CDATA[<img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/roam1.JPG" width="648" height="513"><br><br>面片数跟帧数永远的让人很矛盾。这样以后突变就很不明显?jin),肉眼几乎发现不?jin)Q不q感觉有退化成普通的lod的趋ѝ?br>当然Q远处的|格q是?x)有跛_现象Q不q那已经很远?jin),一般不?x)有人注意到发生了(jin)什么?br>可是q样大大增加?jin)网格数量,应用下视景体剪除效果会(x)比q个好很多吧Q?br><br><img src ="http://www.shnenglu.com/LittleStar/aggbug/96813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-09-21 01:00 <a href="http://www.shnenglu.com/LittleStar/archive/2009/09/21/96813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 roam terrain 的疑?/title><link>http://www.shnenglu.com/LittleStar/archive/2009/09/20/96742.html</link><dc:creator>Little Star</dc:creator><author>Little Star</author><pubDate>Sat, 19 Sep 2009 16:29:00 GMT</pubDate><guid>http://www.shnenglu.com/LittleStar/archive/2009/09/20/96742.html</guid><wfw:comment>http://www.shnenglu.com/LittleStar/comments/96742.html</wfw:comment><comments>http://www.shnenglu.com/LittleStar/archive/2009/09/20/96742.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/LittleStar/comments/commentRss/96742.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/LittleStar/services/trackbacks/96742.html</trackback:ping><description><![CDATA[<img alt="" src="http://www.shnenglu.com/images/cppblog_com/littlestar/roam.JPG" width="498" height="456"><br><br>q个是我实现出来?roam terrain 地Ş<br>问题是,当我在地形上漫游Ӟ|格必然?x)发生变化。不同层ơ的|格之间跌的很厉害Q让得地形很不真实,<br>有没有h有好的办法能解决Q?br><br><img src ="http://www.shnenglu.com/LittleStar/aggbug/96742.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/LittleStar/" target="_blank">Little Star</a> 2009-09-20 00:29 <a href="http://www.shnenglu.com/LittleStar/archive/2009/09/20/96742.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>易飞行仿?—?入R我的镇http://www.shnenglu.com/LittleStar/archive/2009/09/17/96480.htmlLittle StarLittle StarWed, 16 Sep 2009 16:35:00 GMThttp://www.shnenglu.com/LittleStar/archive/2009/09/17/96480.htmlhttp://www.shnenglu.com/LittleStar/comments/96480.htmlhttp://www.shnenglu.com/LittleStar/archive/2009/09/17/96480.html#Feedback7http://www.shnenglu.com/LittleStar/comments/commentRss/96480.htmlhttp://www.shnenglu.com/LittleStar/services/trackbacks/96480.html2.试下引擎框ӞLbug?br>

q张是刚开始时没加载上外部文g时的



q张是爆炸效果图


q张是着火效?br>


被导弹追?br>
最后来张夜色美?br>



诚盼牛h指点不Q?br>

Little Star 2009-09-17 00:35 发表评论
]]>
ҹþþӰԺ| 2020¾þþӾƷ| þþƷˬ97| þþƷƷ޾Ʒ| պŷۺϾþ| Ʒþþþþþþ | ߳þѹۿ| þþþavӰ | ѹ99þþ㽶| þþѹ۳ӰԺ | þþþþùaѹۿ| պþëƬ| ˾þô߽| þֻоƷҳ| ٸþ| þ99ۺϾƷҳ| 66þôýվȸ| ޾ƷþþþþҲ | þ99Ʒ鶹| ۺϾþþ| Ʒ99þaaaһëƬ| ŷԴƬxxxxxþþ| ŷպƷþþѹۿ| ޹ŷۺϾþ| ɫþþ99Ʒ| ˾Ʒþۺ | Ʒþþ99| ھƷ˾þþþ777| 2020þþƷ| þоƷ| ƷþþӰ㽶| ޾ƷƵþþ| þseƷһƷ| þɫۺϼ| Ʒþ8xѹۿ| Ļ޹˾þþƷ| Ʒξþþþ99վ| ޾Ʒþþþþò| aëƬþ| ޾þˬ˾Ʒ| 97Ʒ91þþþþ|