﻿<?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>C++博客-火焰傀偶的挣扎旅程-文章分类-c/c++</title><link>http://www.cppblog.com/WhiteDummy/category/18960.html</link><description>纯爷们的一生就是不停地燃烧，keep on burning soul！！</description><language>zh-cn</language><lastBuildDate>Thu, 18 Aug 2016 11:44:56 GMT</lastBuildDate><pubDate>Thu, 18 Aug 2016 11:44:56 GMT</pubDate><ttl>60</ttl><item><title>cocos2d-x 3.10 lua版本中，listview的优化（基于cocostudio3.10）</title><link>http://www.cppblog.com/WhiteDummy/articles/214188.html</link><dc:creator>WhiteDummy</dc:creator><author>WhiteDummy</author><pubDate>Wed, 17 Aug 2016 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/WhiteDummy/articles/214188.html</guid><wfw:comment>http://www.cppblog.com/WhiteDummy/comments/214188.html</wfw:comment><comments>http://www.cppblog.com/WhiteDummy/articles/214188.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/WhiteDummy/comments/commentRss/214188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/WhiteDummy/services/trackbacks/214188.html</trackback:ping><description><![CDATA[众所周知，cocos的ListView控件并不好用，他最明显的缺点有两个：<br />1.加载大量item时会有明显卡顿<br />2.不支持2维列表<br /><strong><br />&#183;关于listview中item的加载</strong><br /><br />listview中的用法，大约看起来是这样的:<br />1.首先有一个item，并且调用setItemModel<br />2.调用pushBackDefaultItem插入列表，然后从列表取出item并初始化<br />（通过阅读代码可知，这个其实就是1中的item调用clone函数，生成插入item，然后addChild，是一样的）<br /><br />相关代码：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;ListView::addChild(cocos2d::Node&nbsp;*child,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;zOrder,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;tag)<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScrollView::addChild(child,&nbsp;zOrder,&nbsp;tag);<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Widget*&nbsp;widget&nbsp;=&nbsp;dynamic_cast&lt;Widget*&gt;(child);<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">这里可以看出，不是Widget&nbsp;的话，并不会有布局的功能&#8230;&#8230;</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(nullptr&nbsp;!=&nbsp;widget)<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_items.pushBack(widget);<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onItemListChanged();<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">12</span>&nbsp;}</div><br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;ListView::pushBackDefaultItem()<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(nullptr&nbsp;==&nbsp;_model)<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Widget*&nbsp;newItem&nbsp;=&nbsp;_model-&gt;clone();<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remedyLayoutParameter(newItem);//布局排位<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addChild(newItem);<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;requestDoLayout();//设置重新渲染的标记<br /><span style="color: #008080; ">11</span>&nbsp;}</div><br />可以看出，listview的item只支持继承自widget的控件，或者说他的本意如此。<br /><br />基类不是widget的类型，也没有clone方法，那么setItemModel和<span style="font-size: 13px; background-color: #eeeeee;">pushBackDefaultItem这套体系就形同虚设</span><br /><br />然而&#8230;&#8230;cocostudio的新建文件，根本就没有一个父节点是继承自widget的<br /><br />开发过程中，一般一个item就是一个单独的csd，如果想要使用clone，则要每个item的父节点都必须使用一个的panel类型（即&#8220;基础容器&#8221;，实际上只是一个ccui.layout类型&#8230;&#8230;）来替代node节点，这个panel的大小影响布局，而如果item中有嵌套csd的场合，情况则会变得更加麻烦，因为node是无法复制的。<br /><br />综上所述，基本可以得出结论，为了节省工作量，clone这套机制，不如不用。直接create一个csd，再addChild的方案，更加可靠，当然，为了避免上述的布局问题，即使create了csd，还是要先加在一个panel上&#8230;&#8230;<br /><br /><strong>&#183;关于clone方法的效率<br /></strong><br />那么直接使用create的效率比之clone又如何呢？<br />就直接用代码看看呗。<br /><br />cocostudio是可以直接把csb文件导出成lua的，而lua本身又可以再一次压缩luac，这看起来效率还可以<br /><br />试着测试这样一个简单结构的item，创建100个这东东：<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/whitedummy/item5.png" border="0" alt="" /><br /><br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;">local&nbsp;a&nbsp;=&nbsp;require("testItem").create().root:getChildByName("panel_base");<br />local&nbsp;osClock1&nbsp;=&nbsp;os.clock();<br /><span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;=&nbsp;1,&nbsp;100&nbsp;<span style="color: #0000FF; ">do</span><br />&nbsp;&nbsp;&nbsp;&nbsp;a:clone();<br />end<br />print("time:"&nbsp;..&nbsp;os.clock()&nbsp;-&nbsp;osClock1);<br /><br />local&nbsp;osClock2&nbsp;=&nbsp;os.clock();<br /><span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;=&nbsp;1,&nbsp;100&nbsp;<span style="color: #0000FF; ">do</span><br />&nbsp;&nbsp;&nbsp;&nbsp;local&nbsp;a&nbsp;=&nbsp;require("testItem").create().root;<br />end<br />print("time:"&nbsp;..&nbsp;os.clock()&nbsp;-&nbsp;osClock2);</div><br />输出结果为：<br /><img src="http://www.cppblog.com/images/cppblog_com/whitedummy/item4.png" border="0" alt="" /><br />好吧，虽然create慢了点，但还是可以接受的<br /><br />如果item里面的东西复杂，比如我把btn_test(一个默认的按钮控件)，在cocostudio中复制50个，则：<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/whitedummy/item2.png" border="0" alt="" /><br />后来又测试了几个以往项目用的比较复杂的item，基本都是直接create更快了，可见这cocos的clone也是很挫的方法。<br /><br />去瞧瞧c++里的代码，发现他各种属性都要遍历一遍赋值，即是说他没有方法找出重复的值，所以所有的值都要设置一次&#8230;&#8230;上面的使用，想必是因为有很多重复赋值的缘故，才导致慢吧 - -<br /><br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">clone方法的核心代码，一坨属性的赋值</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">void</span>&nbsp;Widget::copyProperties(Widget&nbsp;*widget)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;setEnabled(widget-&gt;isEnabled());<br />&nbsp;&nbsp;&nbsp;&nbsp;setVisible(widget-&gt;isVisible());<br />&nbsp;&nbsp;&nbsp;&nbsp;setBright(widget-&gt;isBright());<br />&nbsp;&nbsp;&nbsp;&nbsp;setTouchEnabled(widget-&gt;isTouchEnabled());<br />&nbsp;&nbsp;&nbsp;&nbsp;setLocalZOrder(widget-&gt;getLocalZOrder());<br />&nbsp;&nbsp;&nbsp;&nbsp;setTag(widget-&gt;getTag());<br />&nbsp;&nbsp;&nbsp;&nbsp;setName(widget-&gt;getName());<br />&nbsp;&nbsp;&nbsp;&nbsp;setActionTag(widget-&gt;getActionTag());<br />&nbsp;&nbsp;&nbsp;&nbsp;_ignoreSize&nbsp;=&nbsp;widget-&gt;_ignoreSize;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>-&gt;setContentSize(widget-&gt;_contentSize);<br />&nbsp;&nbsp;&nbsp;&nbsp;_customSize&nbsp;=&nbsp;widget-&gt;_customSize;<br />&nbsp;&nbsp;&nbsp;&nbsp;_sizeType&nbsp;=&nbsp;widget-&gt;getSizeType();<br />&nbsp;&nbsp;&nbsp;&nbsp;_sizePercent&nbsp;=&nbsp;widget-&gt;_sizePercent;<br />&nbsp;&nbsp;&nbsp;&nbsp;_positionType&nbsp;=&nbsp;widget-&gt;_positionType;<br />&nbsp;&nbsp;&nbsp;&nbsp;_positionPercent&nbsp;=&nbsp;widget-&gt;_positionPercent;<br />&nbsp;&nbsp;&nbsp;&nbsp;setPosition(widget-&gt;getPosition());<br />&nbsp;&nbsp;&nbsp;&nbsp;setAnchorPoint(widget-&gt;getAnchorPoint());<br />&nbsp;&nbsp;&nbsp;&nbsp;setScaleX(widget-&gt;getScaleX());<br />&nbsp;&nbsp;&nbsp;&nbsp;setScaleY(widget-&gt;getScaleY());<br />&nbsp;&nbsp;&nbsp;&nbsp;setRotation(widget-&gt;getRotation());<br />&nbsp;&nbsp;&nbsp;&nbsp;setRotationSkewX(widget-&gt;getRotationSkewX());<br />&nbsp;&nbsp;&nbsp;&nbsp;setRotationSkewY(widget-&gt;getRotationSkewY());<br />&nbsp;&nbsp;&nbsp;&nbsp;setFlippedX(widget-&gt;isFlippedX());<br />&nbsp;&nbsp;&nbsp;&nbsp;setFlippedY(widget-&gt;isFlippedY());<br />&nbsp;&nbsp;&nbsp;&nbsp;setColor(widget-&gt;getColor());<br />&nbsp;&nbsp;&nbsp;&nbsp;setOpacity(widget-&gt;getOpacity());<br />&nbsp;&nbsp;&nbsp;&nbsp;_touchEventCallback&nbsp;=&nbsp;widget-&gt;_touchEventCallback;<br />&nbsp;&nbsp;&nbsp;&nbsp;_touchEventListener&nbsp;=&nbsp;widget-&gt;_touchEventListener;<br />&nbsp;&nbsp;&nbsp;&nbsp;_touchEventSelector&nbsp;=&nbsp;widget-&gt;_touchEventSelector;<br />&nbsp;&nbsp;&nbsp;&nbsp;_clickEventListener&nbsp;=&nbsp;widget-&gt;_clickEventListener;<br />&nbsp;&nbsp;&nbsp;&nbsp;_focused&nbsp;=&nbsp;widget-&gt;_focused;<br />&nbsp;&nbsp;&nbsp;&nbsp;_focusEnabled&nbsp;=&nbsp;widget-&gt;_focusEnabled;<br />&nbsp;&nbsp;&nbsp;&nbsp;_propagateTouchEvents&nbsp;=&nbsp;widget-&gt;_propagateTouchEvents;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;copySpecialProperties(widget);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;Map&lt;<span style="color: #0000FF; ">int</span>,&nbsp;LayoutParameter*&gt;&amp;&nbsp;layoutParameterDic&nbsp;=&nbsp;widget-&gt;_layoutParameterDictionary;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(auto&nbsp;iter&nbsp;=&nbsp;layoutParameterDic.begin();&nbsp;iter&nbsp;!=&nbsp;layoutParameterDic.end();&nbsp;++iter)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setLayoutParameter(iter-&gt;second-&gt;clone());<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br /><strong>&#183;二维布局以及加载优化<br /><br /></strong>这个单从原理上来说，很简单，大致说说我的思路<br />假设listview为竖着滑动的，则通过item的宽度，以及listview的宽度，计算出每一行可以摆的下多少个item，并且得到这个行的高度，以此宽高创建一个panel，并把item都算好坐标addChild到这个panel之中，<br />而这个panel则会被addChild到listview中，这样就实现了二维。<br /><br />然而，加载的问题还是没有解决，listview就是这样的，你的列表有多少个，就给你加载多少个，一次搞定，cocos又没有做到很好的资源剪裁，于是item一多，就卡到爆炸。<br /><br />能想到的解决方案：<br />1.分帧加载<br />2.随滚动加载<br />3.创建固定数量的item（即用户可见的最大数量item），监听滑动事件，根据滑动位置来改变各个item位置，并且根据需要重新初始化item中的内容<br /><br />虽然已经没办法给出具体代码，但是方法1和方法2，甚至方法1和方法2的结合我都有实际在以前项目中使用过。<br /><br />说实话体验比较一般，特别是item复杂的情况，还是会有很明显的卡顿<br /><br />&#8230;&#8230;总之多番试验之后，发现方法3才是最好的。<br /><br />那么怎么用listview去实现呢？listview每添加一个widget类就会自动布局，自己设置滑动范围，对于3的想法来说，实在太不便利，而且我只想在lua中完成这个事情，于是pass。<br /><br />再看看类似的控件怎么做吧，比如cocos2d-iphone时代就有的控件的tableView&#8230;&#8230;<br /><br />这个控件虽然使用起来比较麻烦，但是我认为其性能和扩展性都还可以&#8230;&#8230;该说不愧是元祖鬼佬的cocos2d控件吗，反正比国人设计的这个根本不能商用的玩意要好<br /><br />listview的item在tableview中的名字叫cell，tableview是动态创建item的，他只会创建冒头显示的cell，而且创建的只是一个空的cell，里面的实际内容可以自己定义。<br /><br />tableview也是默认不支持二维数组的，如要需要用上述类似方法自己封装一下，至于动态加载方法，使用一个缓存item的对象池，配合滑动监听和cell初始化的回调方法来实现应该就可以了。<br /><br />&#8230;&#8230;好吧，说了这么多，我最终还是没有选择tableview，而是选择了更底层的scrollview，理由比较单纯，因为cocostudio里面的控件有滑动容器（scrollview），没有tableview。这样可以节省一定的ui工作量&#8230;&#8230;<br /><br /><strong>&#183;实现细节<br /><br /></strong>既然决定了，就创建一个叫CCListViewDynamic的class<br /><br />首先来总结一下，一般初始化一个滑动列表需要的东东：<br />一个lua table，里面存储了一组数据结构（比如排行版的玩家列表）<br />一个scrollView控件，一个item的资源文件，用于重复create<br />一个初始化item的函数指针（比如 通过读取玩家数据，来设置 排名啊 玩家头像 玩家名字之类 ）<br /><br />这些都作为必要的初始化参数传入到CCListViewDynamic中<br /><br />大致流程：（以下是假设滑动方向为垂直，如果是水平也是类似思路）<br /><br /><div>1.通过scrollView的宽高获取应初始化item的个数(可见的行数+1 * 每行的个数)</div>2.创建这些item，并且都addChild到list中，设置坐标为 -width，-height，让其不可见<br />3.遍历一遍lua table，算出每行由哪些item构成，并且算出每个item的坐标，每一行的显示范围并记录（即scrollview:getInnerContainer():getPositionY()在哪个区间时，这行的item依然显示），这个计算只是预计算数据，是没有做渲染相关工作的<br />4.根据上面的遍历，也算出了scrollview的滑动范围。<br /><div>5.根据当前显示范围，通过3中的数据，计算要显示哪些行，如果没有变化，则不继续往下走，否则，和上次显示的范围做比较，计算出今次不显示和新显示的item行数，不显示的item要走一遍2中设置坐标为 -width，-height，让其不可见的流程，新显示的item则要跑一次初始化item的函数指针，并且传入对应的lua table数据</div>6.监听滑动事件，跑一次5的流程（需要注意的是，这个事件在c++中的枚举值是ScrollView::EventType.CONTAINER_MOVED，不知道什么时候添加的，cocos2d-x3.5的版本是没有这个事件的，如果没有就要自己整一个了&#8230;&#8230;）<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/whitedummy/item6.png" border="0" alt="" /><br />上面这里，我试着创建了1000个item，顶点数量和fps还算正常 总体都可以接受&#8230;&#8230;就是初始化速度有点慢，要0.8s，这个还有一些细节有待优化吧。<br /><br />目前只是粗略的做法，还有一些缺点：<br />1.目前还没实现插入自定义item，但是如果要做的话，其实思路也是类似的<br />2.数据和页面耦合太深，如果想做分离式的排序会变得不容易&#8230;&#8230;（比如一个listview里面有两套排序规则的数据）&#8230;&#8230;这个，如果真要有这种变态需求的话，还是有不少地方要改的，但是大体思路依然不变<br /><br />最后附上代码：<a href="/Files/WhiteDummy/mycode/CCListViewDynamic.txt">/Files/WhiteDummy/mycode/CCListViewDynamic.txt</a><a target="null"></a><img src ="http://www.cppblog.com/WhiteDummy/aggbug/214188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/WhiteDummy/" target="_blank">WhiteDummy</a> 2016-08-17 17:14 <a href="http://www.cppblog.com/WhiteDummy/articles/214188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]c++通过模板类巧妙实现单件模式的继承</title><link>http://www.cppblog.com/WhiteDummy/articles/178668.html</link><dc:creator>WhiteDummy</dc:creator><author>WhiteDummy</author><pubDate>Wed, 13 Jun 2012 08:56:00 GMT</pubDate><guid>http://www.cppblog.com/WhiteDummy/articles/178668.html</guid><wfw:comment>http://www.cppblog.com/WhiteDummy/comments/178668.html</wfw:comment><comments>http://www.cppblog.com/WhiteDummy/articles/178668.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/WhiteDummy/comments/commentRss/178668.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/WhiteDummy/services/trackbacks/178668.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "><div>//Singleton.hpp:内容如下 继承使用即可<br /><br />/*<br />用例：<br /><br /><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;DeviceManager&nbsp;:&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;Singleton</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">DeviceManager</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />{</span><span style="color: #0000FF; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "></span><span style="color: #000000; "><br /></span>&nbsp;&nbsp; <span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /></span>&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;ToString()&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000;"><br /></span>&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: #000000;">{<br />&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: #000000; ">printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Hi,&nbsp;I'm&nbsp;DeviceManager.\n</span><span style="color: #000000; ">"</span><span style="color: #000000;">);<br /></span>&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: #000000; ">}<br />};<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;_tmain(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000; ">*</span><span style="color: #000000;">&nbsp;argv[])<br />{<br /></span>&nbsp;&nbsp; <span style="color: #000000; ">DeviceManager::GetInstance()</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">ToString();<br /></span>&nbsp;&nbsp; <span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div></div><br /><br />*/<br /></div><br />#ifndef&nbsp;SINGLETON_H<br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;SINGLETON_H</span><span style="color: #000000; "><br /><br />template&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;Singleton<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;T</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;GetInstance()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;m_instance&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_instance&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;T;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;m_instance;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;ReleaseInstance()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;m_instance&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;m_instance;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_instance&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br /></span><span style="color: #0000FF; ">protected</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton()&nbsp;{}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">virtual</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">~</span><span style="color: #000000; ">Singleton()&nbsp;{}<br /><br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Singleton</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">){};<br />&nbsp;&nbsp;&nbsp;&nbsp;Singleton</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Singleton</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">){};<br /><br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;T</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;m_instance;<br />};<br /><br />template&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />T</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;Singleton</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::m_instance&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br /><br /></span><span style="color: #0000FF; ">#endif</span></div><img src ="http://www.cppblog.com/WhiteDummy/aggbug/178668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/WhiteDummy/" target="_blank">WhiteDummy</a> 2012-06-13 16:56 <a href="http://www.cppblog.com/WhiteDummy/articles/178668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于error LNK1257: code generation failed</title><link>http://www.cppblog.com/WhiteDummy/articles/178516.html</link><dc:creator>WhiteDummy</dc:creator><author>WhiteDummy</author><pubDate>Tue, 12 Jun 2012 06:21:00 GMT</pubDate><guid>http://www.cppblog.com/WhiteDummy/articles/178516.html</guid><wfw:comment>http://www.cppblog.com/WhiteDummy/comments/178516.html</wfw:comment><comments>http://www.cppblog.com/WhiteDummy/articles/178516.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/WhiteDummy/comments/commentRss/178516.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/WhiteDummy/services/trackbacks/178516.html</trackback:ping><description><![CDATA[一般都是使用lib的配置错误的原因，尝试去找所引用第三方库有没合适的lib，如果没有，则应该用自己的环境生成一个&#8230;<br /><br />此情况一般只在release下会发生。<br /><br />我的情况是，所用lib是vs2008（无装sp1）编译的，而自己的工程则装了sp1，于是就出错了。后来重编了一下lib，就正常了。<img src ="http://www.cppblog.com/WhiteDummy/aggbug/178516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/WhiteDummy/" target="_blank">WhiteDummy</a> 2012-06-12 14:21 <a href="http://www.cppblog.com/WhiteDummy/articles/178516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++中关于unicode文本文件的读写</title><link>http://www.cppblog.com/WhiteDummy/articles/169466.html</link><dc:creator>WhiteDummy</dc:creator><author>WhiteDummy</author><pubDate>Thu, 29 Mar 2012 13:24:00 GMT</pubDate><guid>http://www.cppblog.com/WhiteDummy/articles/169466.html</guid><wfw:comment>http://www.cppblog.com/WhiteDummy/comments/169466.html</wfw:comment><comments>http://www.cppblog.com/WhiteDummy/articles/169466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/WhiteDummy/comments/commentRss/169466.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/WhiteDummy/services/trackbacks/169466.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12pt;">只要试过用c++对含有中文的txt进行读写的人，他八成会碰上乱码的问题。</span><br /><br /><span style="font-size: 12pt;">这是因为中文是宽字符表示的，需要用2个窄字符，也既是16位二进制来保存，如果还是用回鬼佬那一套单字节的办法，那么就会全部乱套，自然是显示出一堆不明就里的乱码了~~</span><br /><br /><span style="font-size: 12pt;">在 这里，来谈谈unicode文本文件的读写方法，对于中文文本，网上流传的许多方法都是通过设置setlocale(LC_ALL,  "chs")来解决，我一开始也这么干的，但后来因为项目需求发现这样根本无法解决其他宽字符语言的问题，而且这么做还会影响其他文件的读写，因此这只能算是一个偏门的方法。</span><br /><br /><span style="font-size: 12pt;">我也曾经尝试过用wfstream，wostream来读写文件，可结果行不通，后来想想，还是用最原始的方式，fstream和ostream来做这些事算了。unicode归根到底只是宽字符，要读，只要每次连读两个字节就好。写也是一样的道理。</span><br /><br /><span style="font-size: 12pt;">关键点是：</span><br /><span style="font-size: 12pt;">1.用ofstream打开文件时要加上ios::binary参数，让他以二进制方式读取文件。</span><br /><span style="font-size: 12pt;">2.写文件时要先写入"\xFF\xFE"（即0xFEFF）头，以标识这是一个unicode文件。<br />3.注意换行符是2个宽字符表示的，在windows下是"/r/n"表示换行。<br /><br />下面是一个读写unicode文本的小程序：</span><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">fstream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">istream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;<br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;saveWideFile(&nbsp;ostream</span><span style="color: #000000; ">&amp;</span>&nbsp;<span style="color: #0000FF; ">out</span><span style="color: #000000; ">,&nbsp;wchar_t&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;str,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;size&nbsp;)<br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span>&nbsp;<span style="color: #0000FF; ">const</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pos&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)str;<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(str[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">!=</span>&nbsp;<span style="color: #000000; ">0xFEFF</span><span style="color: #000000; ">)</span><span style="color: #000000; ">/</span><span style="color: #000000; ">写入unicode文件头<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span>&nbsp;<span style="color: #0000FF; ">const</span><span style="color: #000000; ">*</span>&nbsp;<span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;utf16head&nbsp;</span><span style="color: #000000; ">=</span>&nbsp;<span style="color: #000000; ">"</span><span style="color: #000000; ">\xFF\xFE&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">.write(&nbsp;utf16head,&nbsp;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">&nbsp;);<br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">.write(&nbsp;pos,&nbsp;size&nbsp;);<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">预先保存一个a.txt，其内容为：</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;abcdefg<br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;何何何글금기<br /></span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; ">&nbsp;<br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;wc[</span><span style="color: #000000; ">50</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">0</span><span style="color: #000000; ">};</span><span style="color: #008000; ">//</span><span style="color: #008000; ">读取的内容用宽字符保存(其实也可以使用short，更有利于跨平台)</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fstream&nbsp;wfile(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">a.txt</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;ios::binary</span><span style="color: #000000; ">|</span><span style="color: #000000; ">ios::</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wfile.read((</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)wc,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(wc));<br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ofstream&nbsp;</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">b.txt&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;ios::binary&nbsp;</span><span style="color: #000000; ">|</span><span style="color: #000000; ">ios::</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">把a.txt的内容读取，并保存为b.txt</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saveWideFile(</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">,&nbsp;wc,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(wc));<br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">out</span><span style="color: #000000; ">.close();<br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">39</span>&nbsp;</div><span style="border-collapse: separate; color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="color: #010101; font-family: 'Lucida Console'; font-size: 13px;"></span></span> </div><img src ="http://www.cppblog.com/WhiteDummy/aggbug/169466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/WhiteDummy/" target="_blank">WhiteDummy</a> 2012-03-29 21:24 <a href="http://www.cppblog.com/WhiteDummy/articles/169466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>