??xml version="1.0" encoding="utf-8" standalone="yes"?>久久综合久久综合九色,色综合久久久久,亚洲国产精品无码久久久不卡http://www.shnenglu.com/cxiaojia/archive/2013/08/06/202374.htmlC加C加Tue, 06 Aug 2013 11:36:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2013/08/06/202374.htmlhttp://www.shnenglu.com/cxiaojia/comments/202374.htmlhttp://www.shnenglu.com/cxiaojia/archive/2013/08/06/202374.html#Feedback0http://www.shnenglu.com/cxiaojia/comments/commentRss/202374.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/202374.html
float multi = 1.0f;
CCDirector::sharedDirector()->getScheduler()Q?gt;setTimeScale(multi);
参数multi是倍率的意思,默认?,倍率高速度快?br />
如果需要提升一倍的速度Q可以把multi设ؓ2.0f?br />
通过q样一个机制可以实现游戏内战斗倍数加速的功能?img src ="http://www.shnenglu.com/cxiaojia/aggbug/202374.html" width = "1" height = "1" />

C加 2013-08-06 19:36 发表评论
]]>
#pragma once ?#ifndef 解析(?http://www.shnenglu.com/cxiaojia/archive/2013/03/18/198526.htmlC加C加Mon, 18 Mar 2013 02:28:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2013/03/18/198526.htmlhttp://www.shnenglu.com/cxiaojia/comments/198526.htmlhttp://www.shnenglu.com/cxiaojia/archive/2013/03/18/198526.html#Feedback2http://www.shnenglu.com/cxiaojia/comments/commentRss/198526.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/198526.html转自Q?/span>http://blog.csdn.net/slimfox/article/details/1565950
 

Z避免同一个文件被include多次QC/C++中有两种方式Q一U是#ifndef方式Q一U是#pragma once方式。在能够支持q两U方式的~译器上Q二者ƈ没有太大的区别,但是两者仍然还是有一些细微的区别?/span>
    方式一Q?/span>
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 一些声明语?br style="margin: 0px; padding: 0px;" />    #endif

    方式二:
    #pragma once
    ... ... // 一些声明语?/span>

    #ifndef的方式依赖于宏名字不能冲H,q不光可以保证同一个文件不会被包含多次Q也能保证内容完全相同的两个文g不会被不心同时包含。当Ӟ~点是如果不同头文件的宏名不小?#8220;撞R”Q可能就会导致头文g明明存在Q编译器却硬说找不到声明的状?#8212;—q种情况有时非常让h抓狂?/span>
    #pragma once则由~译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文?#8221;是指物理上的一个文Ӟ而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名撞引发的奇怪问题。对应的~点是如果某个头文件有多䆾拯Q本Ҏ不能保证他们不被重复包含。当Ӟ相比宏名撞引发?#8220;找不到声?#8221;的问题,重复包含更容易被发现q修正?/span>
    #pragma once方式产生?ifndef之后Q因此很多h可能甚至没有听说q。目前看?ifndef更受到推崇。因?ifndef受语a天生的支持,不受~译器的M限制Q?pragma once方式却不受一些较老版本的~译器支持,换言之,它的兼容性不够好。也许,再过几年{旧的编译器ȝ了,q就不是什么问题了?/span>
    我还看到一U用法是把两者放在一LQ?/span>
    #pragma once
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 一些声明语?br style="margin: 0px; padding: 0px;" />    #endif

    看v来似乎是惛_有两者的优点。不q只要用了#ifndef׃有宏名冲H的危险Q所以؜用两U方法似乎不能带来更多的好处Q倒是会让一些不熟悉的h感到困惑?/span>
    选择哪种方式Q应该在了解两种方式的情况下Q视具体情况而定。事实上Q只要有一个合理的U定来避开~点Q我认ؓ哪种方式都是可以接受的。而这个已l不是标准或者编译器的责MQ应当由E序员来搞定?/span>
    btwQ我看到GNU的一些讨Z乎是打算在GCC 3.4Q及其以后?Q的版本取消?pragma once的支持。不q我手上GCC 3.4.2和GCC 4.1.1仍然支持#pragma onceQ甚x有deprecation warning。VC6及其以后版本亦提供对#pragma once方式的支持。看来这一Ҏ已l稳定下来了?nbsp;

C加 2013-03-18 10:28 发表评论
]]>
C++Lcd转换模板http://www.shnenglu.com/cxiaojia/archive/2012/04/12/171091.htmlC加C加Thu, 12 Apr 2012 07:13:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/04/12/171091.htmlhttp://www.shnenglu.com/cxiaojia/comments/171091.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/04/12/171091.html#Feedback5http://www.shnenglu.com/cxiaojia/comments/commentRss/171091.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/171091.html#include<iostream>
#include<sstream>
#include<string>
using namespace std;


template<class out_type,class in_value>
out_type convert(const in_value & t)
{
stringstream stream;
stream<<t;//向流中传?/span>
out_type result;//q里存储转换l果
stream>>result;//向result中写入?/span>
return result;
}


int main()
{
    string s;
    while(cin>>s)
    {
        double valdou=convert<double>(s); 
        int valint=convert<int>(s); 
        cout<<valdou<<endl;
        cout<<valint<<endl;
       
      
    }


    return 0;
}

C加 2012-04-12 15:13 发表评论
]]>
自己实现的memcpy()代码http://www.shnenglu.com/cxiaojia/archive/2012/03/13/167815.htmlC加C加Tue, 13 Mar 2012 13:04:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/03/13/167815.htmlhttp://www.shnenglu.com/cxiaojia/comments/167815.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/03/13/167815.html#Feedback1http://www.shnenglu.com/cxiaojia/comments/commentRss/167815.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/167815.html//函数名:mymemcpy
//功能Q内存复?br />//函数说明Q将memFrom指向的空间内容复制给memTo指向的空间内容,大小为size
void* mymemcpy(void* memTo,const void* memFrom,size_t size)
{
    assert(memTo!=NULL);//判断是否为空
    assert(memFrom!=NULL);//判断是否为空
    char *tempFrom=(char*)memFrom;
    char *tempTo=(char*)memTo;
    while(size--)
        *tempTo++=*tempFrom++; //复制
    return memTo;
}

C加 2012-03-13 21:04 发表评论
]]>
学习W记--I类Q虚函数c,虚承类的空间大?/title><link>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167699.html</link><dc:creator>C加</dc:creator><author>C加</author><pubDate>Mon, 12 Mar 2012 02:18:00 GMT</pubDate><guid>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167699.html</guid><wfw:comment>http://www.shnenglu.com/cxiaojia/comments/167699.html</wfw:comment><comments>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167699.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.shnenglu.com/cxiaojia/comments/commentRss/167699.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cxiaojia/services/trackbacks/167699.html</trackback:ping><description><![CDATA[<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: #008000; ">//</span><span style="color: #008000; ">此代码在32位win下运行成?/span><span style="color: #008000; "><br /></span>#include<iostream><br /><span style="color: #0000FF; ">using</span> <span style="color: #0000FF; ">namespace</span> std;<br /><span style="color: #0000FF; ">class</span> A<span style="color: #008000; ">//</span><span style="color: #008000; ">A是空c,~译器会用一个charcd标记q个c,大小?</span><span style="color: #008000; "><br /></span>{<br /><br />};<br /><span style="color: #0000FF; ">class</span> B:<span style="color: #0000FF; ">public</span> A<span style="color: #008000; ">//</span><span style="color: #008000; ">Bl承了AQ但同样也是I类Q大ؓ1</span><span style="color: #008000; "><br /></span>{<br /><br />};<br /><span style="color: #0000FF; ">class</span> C:<span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">public</span> A<span style="color: #008000; ">//</span><span style="color: #008000; ">虚拟l承的时候编译器会安插一个指向父cȝ指针Q大ؓ4</span><span style="color: #008000; "><br /></span>{<br /><br />};<br /><span style="color: #0000FF; ">class</span> D<span style="color: #008000; ">//</span><span style="color: #008000; ">大小?</span><span style="color: #008000; "><br /></span>{<br />  <span style="color: #0000FF; ">public</span>:<br />  <span style="color: #0000FF; ">int</span> a;<br />  <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">int</span> b;<span style="color: #008000; ">//</span><span style="color: #008000; ">静态变量被攑֜静态存储区</span><span style="color: #008000; "><br /></span>};<br /><span style="color: #0000FF; ">class</span> E <span style="color: #008000; ">//</span><span style="color: #008000; ">print函数不占内存I间Q大ؓ4</span><span style="color: #008000; "><br /></span>{<br />    <span style="color: #0000FF; ">public</span>:<br />    <span style="color: #0000FF; ">void</span> print(){cout<<"E"<<endl;}<br />    <span style="color: #0000FF; ">private</span>:<br />    <span style="color: #0000FF; ">int</span> a;<br />};<br /><span style="color: #0000FF; ">class</span> F<span style="color: #008000; ">//</span><span style="color: #008000; ">虚函C占用一个指针大的内存Q系l需要用q个指针l护虚函数表。大ؓ8</span><span style="color: #008000; "><br /></span>{<br />    <span style="color: #0000FF; ">public</span>:<br />    <span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">void</span> print(){cout<<"F"<<endl;}<br />    <span style="color: #0000FF; ">private</span>:<br />    <span style="color: #0000FF; ">int</span> a;<br />};<br /><span style="color: #0000FF; ">class</span> G:<span style="color: #0000FF; ">public</span> F<span style="color: #008000; ">//</span><span style="color: #008000; ">多了一个虚函数内存大小不变Q可见一个类只有一个虚函数指针。大ؓ8</span><span style="color: #008000; "><br /></span>{<br />    <span style="color: #0000FF; ">public</span>:<br />    <span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">void</span> print(){cout<<"G"<<endl;}<br />    <span style="color: #0000FF; ">virtual</span> <span style="color: #0000FF; ">void</span> print2(){cout<<"G2"<<endl;}<br />};<br /><span style="color: #0000FF; ">int</span> main()<br />{<br />    A a;<br />    B b;<br />    C c;<br />    D d;<br />    E e;<br />    F f;<br />    G g;<br />    cout<<<span style="color: #0000FF; ">sizeof</span>(A)<<" "<<<span style="color: #0000FF; ">sizeof</span>(a)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">1 1</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(B)<<" "<<<span style="color: #0000FF; ">sizeof</span>(b)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">1 1</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(C)<<" "<<<span style="color: #0000FF; ">sizeof</span>(c)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">4 4</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(D)<<" "<<<span style="color: #0000FF; ">sizeof</span>(d)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">4 4</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(E)<<" "<<<span style="color: #0000FF; ">sizeof</span>(e)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">4 4</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(F)<<" "<<<span style="color: #0000FF; ">sizeof</span>(f)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; "> 8 8</span><span style="color: #008000; "><br /></span>    cout<<<span style="color: #0000FF; ">sizeof</span>(G)<<" "<<<span style="color: #0000FF; ">sizeof</span>(g)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; ">8 8</span><span style="color: #008000; "><br /></span><br />    <span style="color: #0000FF; ">return</span> 0;<br />}</div><img src ="http://www.shnenglu.com/cxiaojia/aggbug/167699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cxiaojia/" target="_blank">C加</a> 2012-03-12 10:18 <a href="http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习W记--const的作?/title><link>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167695.html</link><dc:creator>C加</dc:creator><author>C加</author><pubDate>Mon, 12 Mar 2012 01:35:00 GMT</pubDate><guid>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167695.html</guid><wfw:comment>http://www.shnenglu.com/cxiaojia/comments/167695.html</wfw:comment><comments>http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167695.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/cxiaojia/comments/commentRss/167695.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cxiaojia/services/trackbacks/167695.html</trackback:ping><description><![CDATA[<div><p>C++<span style="font-family:宋体;">中的</span>const<span style="font-family:宋体;">关键字和</span>#define<span style="font-family:宋体;">有些怼Q?/span>#define<span style="font-family:宋体;">只是用来做文本替换的Q会出现一些错误ƈ且不Ҏ查到。在</span>C++<span style="font-family:宋体;">代码中尽量?/span>const<span style="font-family:宋体;">而不?/span>#define<span style="font-family:宋体;">?/span></p> <p> </p> <p>const<span style="font-family:宋体;">的作用:</span></p> <p style="margin-left:18.0pt;text-indent:-18.0pt;">1?nbsp;const<span style="font-family:宋体;">用于定义帔RQ?/span>const<span style="font-family:宋体;">定义的常量编译器可以对其q行数据静态类型安全检查?/span></p> <p style="margin-left:18.0pt;text-indent:-18.0pt;">2?nbsp;const<span style="font-family:宋体;">修饰形参Q当参数是用戯定义cd或者抽象数据类型时Q用</span>const<span style="font-family:宋体;">引用传递而不是g递可以提高效率?/span></p> <p style="margin-left:18.0pt;text-indent:0cm;">Void fun1(A a);</p> <p style="margin-left:18.0pt;text-indent:0cm;">Void fun2(A const &a);</p> <p style="margin-left:18.0pt;text-indent:0cm;"><span style="font-family:宋体;">W二个函C需要生时对象,省去了对象构造析构消耗的旉</span></p> <p style="margin-left:18.0pt;text-indent:-18.0pt;">3?nbsp;const<span style="font-family:宋体;">修饰函数q回|如果函数q回一?/span>const<span style="font-family:宋体;">指针Q则函数q回值只能被</span>const<span style="font-family:宋体;">同类型指针接Ӟ否则</span>error<span style="font-family:宋体;">?/span></p> <p style="margin-left:18.0pt;text-indent:-18.0pt;">4?nbsp;const<span style="font-family:宋体;">修饰成员函数Q当你的成员函数不需要改变数据成员的值时Q就加上</span>const<span style="font-family:宋体;">修饰?/span></p></div><img src ="http://www.shnenglu.com/cxiaojia/aggbug/167695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cxiaojia/" target="_blank">C加</a> 2012-03-12 09:35 <a href="http://www.shnenglu.com/cxiaojia/archive/2012/03/12/167695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习W记--main函数l束后的调用http://www.shnenglu.com/cxiaojia/archive/2012/03/11/167667.htmlC加C加Sun, 11 Mar 2012 11:46:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/03/11/167667.htmlhttp://www.shnenglu.com/cxiaojia/comments/167667.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/03/11/167667.html#Feedback1http://www.shnenglu.com/cxiaojia/comments/commentRss/167667.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/167667.html

本以Z函数main是首先被调用的函敎ͼ后来发现操作pȝ会调用一个启动函敎ͼ?/span>C++q行库进行初始化?/span>

本以Z函数main被返回之后操作系l将回收资源Q却不知一个重要的函数—atexit()?/span>

 

E序退出的时候需要一些诸如释放资源的操作Q但是程序的退出有很多U,可能?/span>main函数l束范围一个g递给exit()Q也可能是一些其他的原因Q所以需要一U与E序l束方式无关的方法来q行E序退出时必要的处理?/span>

 

函数原型Q?/span>int atexit(void(*)(void));

函数作用Q注册一个函敎ͼq个函数在程序结束的时候被调用

#include<cstdlib>
#include<iostream>
using namespace std;

void fun1()
{
    cout<<"fun1"<<endl;
}
void fun2()
{
    cout<<"fun2"<<endl;
}

int main()
{
    atexit(fun1);//注册fun1Q主函数l止时调?/span>
    atexit(fun2);//注册fun2Q主函数l止时调?/span>
    cout<<"mian exit"<<endl;
    return 0;
}


//q行l果Q?/span>
main exit
fun2
fun1


从结果中可以发现fun1和fun2两个函数在主函数l束之后被调用,而且调用的顺序与注册的顺序相反?/p>




C加 2012-03-11 19:46 发表评论
]]>
3U交换变量值的Ҏhttp://www.shnenglu.com/cxiaojia/archive/2012/03/07/167347.htmlC加C加Wed, 07 Mar 2012 14:03:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/03/07/167347.htmlhttp://www.shnenglu.com/cxiaojia/comments/167347.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/03/07/167347.html#Feedback3http://www.shnenglu.com/cxiaojia/comments/commentRss/167347.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/167347.html
//中间变量?/span>
void swap1(int& a,int& b)
{
    int temp=a;
    a=b;
    b=temp;
}
//怺加减?/span>
void swap2(int& a,int& b)
{
    a=a+b;//可能会溢?/span>
    b=a-b;
    a=a-b;
}
//异或?/span>
void swap3(int& a,int& b)
{
    a^=b;
    b^=a;
    a^=b;
}

C加 2012-03-07 22:03 发表评论
]]>
自己实现的strcpy()和strlen()代码http://www.shnenglu.com/cxiaojia/archive/2012/02/25/166471.htmlC加C加Sat, 25 Feb 2012 02:00:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/02/25/166471.htmlhttp://www.shnenglu.com/cxiaojia/comments/166471.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/02/25/166471.html#Feedback7http://www.shnenglu.com/cxiaojia/comments/commentRss/166471.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/166471.html//函数名:mystrcpy
//功能Q字W串的复?br />//函数说明Q从strSrc地址开始的字符串赋值给strDestQ两者都不能为空
char* mystrcpy(char* strDest,const char* strSrc)
{
    assert(strDest!=NULL);//断言Q如果表辑ּ为假则输出错误信?/span>
    assert(strSrc!=NULL);
    char* p=strDest;
    while((*strDest++=*strSrc++)!='\0');
    return p;
}

//函数名:mystrlen
//功能Q字W串的个数统?br />//函数说明Q统计字W串中字W的长度Q不包括'\0'Q字W串不能为空
unsigned int mystrlen(const char* str)
{
    assert(str!=NULL);
   unsigned int cnt=0;
    while(*str++!='\0') cnt++;
    return cnt;
}

C加 2012-02-25 10:00 发表评论
]]>
自己实现的atof()和atoi()代码http://www.shnenglu.com/cxiaojia/archive/2012/02/24/166436.htmlC加C加Fri, 24 Feb 2012 08:42:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/02/24/166436.htmlhttp://www.shnenglu.com/cxiaojia/comments/166436.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/02/24/166436.html#Feedback3http://www.shnenglu.com/cxiaojia/comments/commentRss/166436.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/166436.html
//函数名:myatof
//功能Q把字符串{化成double点?br />//名字来源Qmy array to floating point numbers  
//函数说明Q接收一个字W串判断W一个字W的W号Q没有符号默认ؓ正|然后对剩余字W串q行转换Q?/span>//遇到\0l束Q最后返回一个double

double myatof(const char* sptr)
{
    double temp=10;
    bool ispnum=true;
    double ans=0;
    if(*sptr=='-')//判断是否是负?/span>
    {
        ispnum=false;
        sptr++;
    }
    else if(*sptr=='+')//判断是否为正?/span>
    {
        sptr++;
    }

    while(*sptr!='\0')//L数点之前的?/span>
    {
        if(*sptr=='.'){ sptr++;break;}
        ans=ans*10+(*sptr-'0');
        sptr++;
    }
    while(*sptr!='\0')//L数点之后的?/span>
    {
        ans=ans+(*sptr-'0')/temp;
        temp*=10;
        sptr++;
    }
    if(ispnum) return ans;
    else return ans*(-1);
}

//函数名:myatoi
//功能Q把字符串{化成int整型
//名字来源Qmy array to integer  
//函数说明Q接收一个字W串判断W一个字W的W号Q没有符号默认ؓ正|然后对剩余字W串q行转换Q?/span>//遇到\0l束Q最后返回一个int

int myatoi(const char* sptr)
{

    bool ispnum=true;
    int ans=0;
    if(*sptr=='-')//判断是否是负?/span>
    {
        ispnum=false;
        sptr++;
    }
    else if(*sptr=='+')//判断是否为正?/span>
    {
        sptr++;
    }

    while(*sptr!='\0')//cd转化
    {
        ans=ans*10+(*sptr-'0');
        sptr++;
    }

    if(ispnum) return ans;
    else return ans*(-1);
}


C加 2012-02-24 16:42 发表评论
]]>
学习W记--extern关键?/title><link>http://www.shnenglu.com/cxiaojia/archive/2012/02/23/166300.html</link><dc:creator>C加</dc:creator><author>C加</author><pubDate>Thu, 23 Feb 2012 00:04:00 GMT</pubDate><guid>http://www.shnenglu.com/cxiaojia/archive/2012/02/23/166300.html</guid><wfw:comment>http://www.shnenglu.com/cxiaojia/comments/166300.html</wfw:comment><comments>http://www.shnenglu.com/cxiaojia/archive/2012/02/23/166300.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/cxiaojia/comments/commentRss/166300.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cxiaojia/services/trackbacks/166300.html</trackback:ping><description><![CDATA[<div><p>extern<span style="font-family:宋体;">关键字的作用</span></p> <p style="margin-left:18.0pt;text-indent:-18.0pt;">1?nbsp;<span style="font-family:宋体;">声明外部变量或者函?/span></p> <p style="margin-left: 18pt; text-indent: 0cm; "><span style="font-family:宋体;">当你所需要的变量或者函数在另一个文仉边的时候,除了?/span>include<span style="font-family:宋体;">包含Q还可以?/span>extern<span style="font-family:宋体;">声明外部变量或者函数?br /><br /></span></p><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: #008000; ">//</span><span style="color: #008000; ">File1.cpp</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span> a;<br /><span style="color: #0000FF; ">int</span> fun(<span style="color: #0000FF; ">int</span> w)<br />{<br />        <span style="color: #0000FF; ">return</span> ++w;<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">main.cpp</span><span style="color: #008000; "><br /></span>#include<iostream><br /><span style="color: #0000FF; ">using</span> <span style="color: #0000FF; ">namespace</span> std;<br /><span style="color: #0000FF; ">int</span> main()<br />{<br />        <span style="color: #0000FF; ">extern</span> <span style="color: #0000FF; ">int</span> a;<span style="color: #008000; ">//</span><span style="color: #008000; ">声明外部变量</span><span style="color: #008000; "><br /></span>        <span style="color: #0000FF; ">extern</span> <span style="color: #0000FF; ">int</span> fun(<span style="color: #0000FF; ">int</span> w);<span style="color: #008000; ">//</span><span style="color: #008000; ">声明外部函数</span><span style="color: #008000; "><br /></span><br />        a=5;<br />        cout<<a<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; "> 5</span><span style="color: #008000; "><br /></span>        cout<<fun(a)<<endl;<span style="color: #008000; ">//</span><span style="color: #008000; "> 6</span><span style="color: #008000; "><br /></span>        <span style="color: #0000FF; ">return</span> 0;<br />}</div><div><p>q里要注意的一ҎQextern关键字的作用仅仅是声明,没有分配内存I间Q声明的格式和定义的格式一定要严格相符?/p></div><span style="font-family: 宋体; "><br /></span><div><p style="margin-left:18.0pt;text-indent:-18.0pt;">2?extern ”C” 链接指定为C函数?/p> <p style="margin-left: 18pt; text-indent: 0cm; ">参数重蝲是C++的新Ҏ,在C中是没有的。在使用C++写代码的时候,如果调用C函数出错Q出错的原因见C++重蝲的实现机ӞQ则需要声明extern “C”链接指定ؓC函数库?/p></div>      <div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 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 />--><br /><span style="color: #0000FF; ">extern</span> "C" <br />{<br />  <span style="color: #008000; ">/*</span><span style="color: #008000; "><img src="http://www.shnenglu.com/Images/dot.gif" alt="" /></span><span style="color: #008000; ">*/</span><br />  }</div><span style="font-family: 宋体; "><br /><br /></span><p> </p></div><img src ="http://www.shnenglu.com/cxiaojia/aggbug/166300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cxiaojia/" target="_blank">C加</a> 2012-02-23 08:04 <a href="http://www.shnenglu.com/cxiaojia/archive/2012/02/23/166300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习W记--static变量与普通变量的区别http://www.shnenglu.com/cxiaojia/archive/2012/02/22/166228.htmlC加C加Wed, 22 Feb 2012 05:10:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2012/02/22/166228.htmlhttp://www.shnenglu.com/cxiaojia/comments/166228.htmlhttp://www.shnenglu.com/cxiaojia/archive/2012/02/22/166228.html#Feedback1http://www.shnenglu.com/cxiaojia/comments/commentRss/166228.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/166228.html

静态全局变量与普通全局变量Q两者的存储方式相同Q都存储在静态区Q静态全局变量的作用域是定义该变量的源文gQ普通全局变量的作用域则是多个源文件的源程序,静态全局变量只初始化一ơ。?/span>

 

静态局部变量与普通局部变?/span>Q两者的作用域相同,存储方式不同Q静态局部变量存储在静态区Q普通局部变量存储在栈区。生存期也不同,静态局部变量的生存期ؓ整个E序Q普通局部变量的生存期仅为定义的那段I间。静态局部变量只初始化一ơ?/span>

 

静态函C普通函?/span>Q作用域不同Q静态函数的作用域仅在被定义的源文gQ普通函数在头文件的辅助下可以被外部讉K。静态函数在内存中只有一份,而普通函数在内存中可以有一份或者多份拷贝?/span>



C加 2012-02-22 13:10 发表评论
]]>
学习W记--C++重蝲Q参数多态)的实现机?/title><link>http://www.shnenglu.com/cxiaojia/archive/2012/02/21/166171.html</link><dc:creator>C加</dc:creator><author>C加</author><pubDate>Tue, 21 Feb 2012 13:07:00 GMT</pubDate><guid>http://www.shnenglu.com/cxiaojia/archive/2012/02/21/166171.html</guid><wfw:comment>http://www.shnenglu.com/cxiaojia/comments/166171.html</wfw:comment><comments>http://www.shnenglu.com/cxiaojia/archive/2012/02/21/166171.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/cxiaojia/comments/commentRss/166171.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cxiaojia/services/trackbacks/166171.html</trackback:ping><description><![CDATA[<div><p>C++<span style="font-family:宋体;">l承?/span>C<span style="font-family:宋体;">的全部特性,?/span>C<span style="font-family:宋体;">实现了全面兼宏V?/span>C++<span style="font-family:宋体;">又实C一些新的特性,比如说函数的重蝲?/span></p> <p><span style="font-family:宋体;">要实现函数的重蝲p改变原有的在</span>C<span style="font-family:宋体;">中函数定义的机制Q在</span>C<span style="font-family:宋体;">中定义函?/span>fun(int a,int b)<span style="font-family:宋体;">Q编译器会把</span>_fun<span style="font-family:宋体;">写入W号库中Q?/span>fun()<span style="font-family:宋体;">时会在符号库中找?/span>_fun<span style="font-family:宋体;">Qƈ调用?/span></p> <p><span style="font-family:宋体;">?/span>C++<span style="font-family:宋体;">中,׃要实现重载,需要加上参数的Ҏ,于是变成了</span>_fun_int_int<span style="font-family:宋体;">Q当函数?/span>fun(int a,double b)<span style="font-family:宋体;">Ӟ~译器就会把</span>_fun_int_double<span style="font-family: 宋体; ">写入W号库,q样实C参数的多态?/span></p> <p> </p></div><img src ="http://www.shnenglu.com/cxiaojia/aggbug/166171.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cxiaojia/" target="_blank">C加</a> 2012-02-21 21:07 <a href="http://www.shnenglu.com/cxiaojia/archive/2012/02/21/166171.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组名是指针么?http://www.shnenglu.com/cxiaojia/archive/2011/12/23/shuzuming.htmlC加C加Fri, 23 Dec 2011 14:27:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2011/12/23/shuzuming.htmlhttp://www.shnenglu.com/cxiaojia/comments/162695.htmlhttp://www.shnenglu.com/cxiaojia/archive/2011/12/23/shuzuming.html#Feedback2http://www.shnenglu.com/cxiaojia/comments/commentRss/162695.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/162695.html
我叙qC下我所知道的数l名与指针的区别?br />
1、地址相同Q大不?/strong>
看下面代码:
1     int arr[10];
2     int* p=arr;
3     cout<<arr<<endl;
4     cout<<p<<endl;
5     cout<<sizeof(arr)<<endl;//l果?0
6     cout<<sizeof(p)<<endl;//l果?

arr为数l名Qp为指针?br />W??行输出的gP也就是说arr和p都是数组的首地址。第5?行的l果不一Parr的大是整个数组的大,而p的大是指针的大?br />Z么arr的大会?0Q?br />
2、都可以用指针作为Ş?/strong>
指针的Ş参当然是指针。数l的形参可以是数l,也可以是指针。下面代码印证了数组的Ş参可以是指针?br />
 1 void fun(int* p)
 2 {
 3     cout<<p[0]<<endl;
 4 }
 5 
 6 
 7 int main()
 8 {
 9     int arr[10]={0};
10     int* p=arr;
11     fun(arr);
12     
13     return 0;
14 }

q点可以看出Q数l名完全可以当成指针来用?br />
3、指针可以自加,数组名不可以

1     int arr[10]={0};
2     int* p=arr;
3     arr++;
4     p++;

当数l名自加时程序编译就会出错,从这点应该可以看出,数组名是一个常量(const 修饰Q?br />

4、作为参数的数组名的大小和指针的大小相同

1 void fun(int arr[])
2 {
3     cout<<sizeof(arr)<<endl;//l果?
4     arr++;//~译成功
5 }
6 

arr的大变?、arr++成功~译可以定Q作为参数的arr已经完全变成了一个指针?br />
以上是我所知道的指针与数组名的区别Q如果还有别的区别请留言告诉我,如果谁知道数l名到底是一U什么样的结构,也请留言告知Q谢谢哈?br />





C加 2011-12-23 22:27 发表评论
]]>
C++实现单例模式http://www.shnenglu.com/cxiaojia/archive/2011/12/21/danli.htmlC加C加Wed, 21 Dec 2011 06:41:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2011/12/21/danli.htmlhttp://www.shnenglu.com/cxiaojia/comments/162531.htmlhttp://www.shnenglu.com/cxiaojia/archive/2011/12/21/danli.html#Feedback15http://www.shnenglu.com/cxiaojia/comments/commentRss/162531.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/162531.html
单例模式QSingleton 
单例模式保某一个类只有一个实例,而且自行实例化ƈ向整个系l提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用?br />
我实C一个简单的单例c,Ƣ迎吐槽?br />
#include<iostream>
using namespace std;

class Singleton
{
public:
    
static Singleton * GetInstance()//通过静态公有函数获得该cȝ实例对象
    {
        
if(m_pInstance==NULL)
        m_pInstance
=new Singleton();
        
return m_pInstance;
    }

private:
    Singleton(){}
//构造函数私有化的目的是Z防止从别处实例化该类对象
    static Singleton * m_pInstance;
    
class Garbo//删除Singleton实例的对?/span>
    {
    
public:
        
~Garbo()
        {
            
if(Singleton::m_pInstance)
            {
                delete Singleton::m_pInstance;
            }
        }
    };
    
static Garbo gb;//在程序结束时Q系l会调用它的析构函数
};
Singleton 
* Singleton::m_pInstance=NULL;//初始化静态数据成?br />
int main()
{
    Singleton 
*sl=Singleton::GetInstance();
    
return 0;
}


C加 2011-12-21 14:41 发表评论
]]>
学习W记--C/C++内存划分http://www.shnenglu.com/cxiaojia/archive/2011/11/30/neicun.htmlC加C加Wed, 30 Nov 2011 03:31:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2011/11/30/neicun.htmlhttp://www.shnenglu.com/cxiaojia/comments/161222.htmlhttp://www.shnenglu.com/cxiaojia/archive/2011/11/30/neicun.html#Feedback0http://www.shnenglu.com/cxiaojia/comments/commentRss/161222.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/161222.html

关于C++内存的划分,|上的ȝ已经很详l了。下Ҏ我{载的一部分?br />
一、一个经q编译的C/C++的程序占用的内存分成以下几个部分Q?/p>

 

  1、栈区(stackQ:q译器自动分配和释放,存放函数的参数倹{局部变量的值等Q甚臛_数的调用q程都是用栈来完成。其操作方式cM于数据结构中的栈?/p>

 

  2、堆区(heapQ?Q一般由E序员手动申请以及释放, 若程序员不释放,E序l束时可能由OS回收。注意它与数据结构中的堆是两回事Q分配方式类g链表?/p>

 

  3、全局区(静态区Q(staticQ:全局变量和静态变量的存储是放在一块的Q初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在盔R的另一块区域。程序结束后ql释攄间?/p>

 

  4、文字常量区Q常量字W串是攑֜q里的?E序l束后由pȝ释放I间?/p>

 

  5、程序代码区Q存攑ևC的二q制代码?/p>

 

  下面的例子可以完全展CZ同的变量所占的内存区域Q?/p>

 

 
  int a = 0; 全局初始化区
 
  char *p1; 全局未初始化?br /> 
  main()
 
  {
 
  int b; //栈中
 
  char s[] = "abc"; //栈中
 
  char *p2; //栈中
 
  char *p3 = "123456"; //123456\0在常量区Qp3在栈?/span>
 
  static int c =0Q?nbsp;//全局Q静态)初始化区
 
  
//以下分配得到?0?0字节的区域就在堆?/span>
 
  p1 = (char *)malloc(10);
 
  p2 = new char[20];//(char *)malloc(20);
 
  strcpy(p1, "123456"); //123456\0攑֜帔R区,~译器可能会它与p3所指向?123456"优化成一个地斏V?/span>
 
  }

 

  二、栈QstackQ和堆(heapQ具体的区别?/p>

 

  1、在甌方式?/p>

 

  栈(stackQ? 现在很多人都UC为堆栈,q个时候实际上q是指的栈。它q译器自动理Q无需我们手工控制。例如,声明函数中的一个局部变?int b pȝ自动在栈中ؓb开辟空_在调用一个函数时Q系l自动的l函数的形参变量在栈中开辟空间?/p>

 

  堆(heapQ? 甌和释攄E序员控Ӟq指明大。容易生memory leak?/p>

 

  在C中用malloc函数?/p>

 

  如:p1 = (char *)malloc(10);

 

  在C++中用newq算W?/p>

 

  如:p2 = new char[20];//(char *)malloc(10);

 

  但是注意p1本n在全局区,而p2本n是在栈中的,只是它们指向的空间是在堆中?br />
      new的本质还是用malloc的,但是new和mallocq是有很大区别:

      Q?Qmalloc是C语言中的函数Qnew是C++中的操作W?br />
      Q?Qmalloc的返回值是VOID*Qnewq回值是带有cd?br />
      Q?Qmalloc只负责分配内存而不会调用类的构造函敎ͼnew不仅会分配内存,q会调用cȝ构造函?/p>

 

  2、申请后pȝ的响应上

 

  栈(stackQ?只要栈的剩余I间大于所甌I间Q系l将为程序提供内存,否则报异常提示栈溢出?/p>

 

  堆(heapQ? 首先应该知道操作pȝ有一个记录空闲内存地址的链表,当系l收到程序的甌Ӟ会遍历该链表Q寻扄一个空间大于所甌I间的堆l点Q然后将该结点从I闲l点链表中删除,q将该结点的I间分配l程序。另外,对于大多数系l,会在q块内存I间中的首地址处记录本ơ分配的大小Q这P代码中的delete或free语句才能正确的释放本内存I间。另外,׃扑ֈ的堆l点的大不一定正好等于申L大小Q系l会自动的将多余的那部分重新攑օI闲链表中?/p>

 

 3、申请大的限制

 

  栈(stackQ?在Windows?栈是向低地址扩展的数据结构,是一块连l的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是pȝ预先规定好的Q在Windows下,栈的大小?MQ也有的说是1MQM是一个编译时q定的常数Q,如果甌的空间超q栈的剩余空间时Q将提示overflow。因此,能从栈获得的I间较小。例如,在VC6下面Q默认的栈空间大是1MQ好像是Q记不清楚了Q。当Ӟ我们可以修改Q打开工程Q依ơ操作菜单如下:Project->Setting->LinkQ在Category 中选中OutputQ然后在Reserve中设定堆栈的最大值和commit?/p>

 

  注意Qreserve最gؓ4ByteQcommit是保留在虚拟内存的页文g里面Q它讄的较大会使栈开辟较大的|可能增加内存的开销和启动时间?/p>

 

  堆(heapQ? 堆是向高地址扩展的数据结构,是不q箋的内存区域(I闲部分用链表串联v来)。正是由于系l是用链表来存储I闲内存Q自然是不连l的Q而链表的遍历方向是由低地址向高地址。一般来讲在32位系l下Q堆内存可以辑ֈ4G的空_从这个角度来看堆内存几乎是没有什么限制的。由此可见,堆获得的I间比较灉|Q也比较大?/p>

 

  4、分配空间的效率?/p>

 

  栈(stackQ?栈是机器pȝ提供的数据结构,计算Z在底层对栈提供支持:分配专门的寄存器存放栈的地址Q压栈出栈都有专门的指o执行Q这决定了栈的效率比较高。但E序员无法对其进行控制?/p>

 

  堆(heapQ?是C/C++函数库提供的Q由new或malloc分配的内存,一般速度比较慢,而且Ҏ产生内存片。它的机制是很复杂的Q例如ؓ了分配一块内存,库函C按照一定的法Q具体的法可以参考数据结?操作pȝQ在堆内存中搜烦可用的够大的I间Q如果没有够大的I间Q可能是׃内存片太多Q,有可能调用pȝ功能d加程序数据段的内存空_q样有Z分到_大小的内存,然后q行q回。这样可能引发用h和核心态的切换Q内存的甌Q代价变得更加昂c显Ӟ堆的效率比栈要低得多?/p>

 

  5、堆和栈中的存储内容

 

  栈(stackQ?在函数调用时Q第一个进栈的是主函数中子函数调用后的下一条指令(子函数调用语句的下一条可执行语句Q的地址Q然后是子函数的各个形参。在大多数的C~译器中Q参数是由右往左入栈的Q然后是子函C的局部变量。注意:静态变量是不入栈的。当本次函数调用l束后,局部变量先出栈Q然后是参数Q最后栈指针指向最开始存的地址Q也是dC子函数调用完成的下一条指令,E序p点l运行?/p>

 

  堆(heapQ?一般是在堆的头部用一个字节存攑֠的大,堆中的具体内ҎE序员安排?/p>

 

  6、存取效率的比较

 

  q个应该是显而易见的。拿栈上的数l和堆上的数l来_

 

 


 void main()
 
  {
 
  int arr[5]={1,2,3,4,5};
 
  int *arr1;
 
  arr1=new int[5];
 
  for (int j=0;j<=4;j++)
 
  {
 
  arr1[j]=j+6;
 
  }
 
  int a=arr[1];
 
  int b=arr1[1];
 
  }

 

  上面代码中,arr1Q局部变量)是在栈中Q但是指向的I间在堆上Q两者的存取效率Q当然是arr高。因为arr[1]可以直接讉KQ但是访问arr1[1]Q首先要讉K数组的v始地址arr1Q然后才能访问到arr1[1]?/p>

 

  总而言之,a而MQ?/p>

 

  堆和栈的区别可以用如下的比喻来看出:

 

  使用栈就象我们去饭馆里吃饭,只管点菜Q声明变量)、付钱、和吃(使用Q,吃饱了就赎ͼ不必理会切菜、洗菜等准备工作和洗、刷锅等扫尾工作Q他的好处是快捷Q但是自由度?/p>

 

  使用堆就象是自己动手做喜Ƣ吃的菜_比较ȝQ但是比较符合自q口味Q而且自由度大?/p>

C加 2011-11-30 11:31 发表评论
]]>
关于拯Q复Ӟ构造函Cؓ什么不能用g?/title><link>http://www.shnenglu.com/cxiaojia/archive/2011/11/22/cpp1.html</link><dc:creator>C加</dc:creator><author>C加</author><pubDate>Tue, 22 Nov 2011 11:46:00 GMT</pubDate><guid>http://www.shnenglu.com/cxiaojia/archive/2011/11/22/cpp1.html</guid><wfw:comment>http://www.shnenglu.com/cxiaojia/comments/160730.html</wfw:comment><comments>http://www.shnenglu.com/cxiaojia/archive/2011/11/22/cpp1.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/cxiaojia/comments/commentRss/160730.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/cxiaojia/services/trackbacks/160730.html</trackback:ping><description><![CDATA[当你试着把拷贝构造函数写成g递的时候,会发现编译都通不q,错误信息如下Q?br /><span style="color: red; ">error: invalid constructor; you probably meant 'S (const S&)' </span>Q大致意思是Q无效的构造函敎ͼ你应该写成。。。)<br />当编译错误的时候你开始纠l了Qؓ什么拷贝构造函C定要使用引用传递呢Q我上网查找了许多资料,大家的意思基本上都是说如果用g递的话可能会产生d@环。编译器可能Zq样的原因不允许出现g递的拯构造函敎ͼ也有可能是C++标准是这栯定的?div><br />如果真是产生d@环这个原因的话,应该是这样子的:<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 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: #000000; "><br />#include</span><span style="color: #000000; "><</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">></span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> std;<br /></span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> S<br />{<br />  </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> a;<br />  </span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />  S(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> x):a(x){}<br />  S(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; "> S st){</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">-></span><span style="color: #000000; ">a</span><span style="color: #000000; ">=</span><span style="color: #000000; ">st.a;}</span><span style="color: #008000; ">//</span><span style="color: #008000; ">拯构造函?/span><span style="color: #008000; "><br /></span><span style="color: #000000; ">};<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> main()<br />{<br />    S s1(</span><span style="color: #000000; ">2</span><span style="color: #000000; ">);<br />    S s2(s1);<br /><br /><br />    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /></span></div>当给s2初始化的时候调用了s2的拷贝构造函敎ͼ׃是g递,pȝ会给形参st重新甌一D늩_然后调用自n的拷贝构造函数把s1的数据成员的glst。当调用自n的拷贝构造函数的时候又因ؓ是g递,所以。。?br />也就是说Q只要调用拷贝构造函敎ͼ׃重新甌一D늩_只要重新甌一D늩_׃调用拯构造函敎ͼq样一直下d形成了一个死循环?br />所以拷贝构造函C定不能是g递?br /><br /><br /><br /><br /><br /><br /></div><img src ="http://www.shnenglu.com/cxiaojia/aggbug/160730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/cxiaojia/" target="_blank">C加</a> 2011-11-22 19:46 <a href="http://www.shnenglu.com/cxiaojia/archive/2011/11/22/cpp1.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CC++风格的新元素http://www.shnenglu.com/cxiaojia/archive/2011/11/14/xdfg.htmlC加C加Mon, 14 Nov 2011 05:07:00 GMThttp://www.shnenglu.com/cxiaojia/archive/2011/11/14/xdfg.htmlhttp://www.shnenglu.com/cxiaojia/comments/160077.htmlhttp://www.shnenglu.com/cxiaojia/archive/2011/11/14/xdfg.html#Feedback0http://www.shnenglu.com/cxiaojia/comments/commentRss/160077.htmlhttp://www.shnenglu.com/cxiaojia/services/trackbacks/160077.html

“C++11像一门新的语a?#8221; – Bjarne Stroustrup

C++11标准推出了很多有用的新特性。本文特别关注相比C++98更像是一门新语言的那部分Ҏ,因ؓQ?/p>

q些Ҏ改变了~写C++E序使用的代码风格和习语[TODO]Q通常也包括你设计C++函数库的方式。例如,你会看到更多参数和返回值类型ؓ指针(smart pointer)Q同时也会看到函数通过g递返回大型对?/p>

你将会发现在大多数的代码CZ中充斥着新特性的w媄。例如,几乎?行现代C++代码CZ都会使用?strong>auto

C++11的其他特性也很棒。但是请先熟悉下面这些,正是因ؓq些Ҏ的q泛使用使得C++11代码如同其他CL语言一hz、安全和高效Q与此同时保持了C++传统的性能优势?/p>

提示Q?/p>

  • 与Strunk & White[TODO]一P本文只做概要的ȝ性指D不做详基本原理和优缺点分析。详l分析请参见其他文章
  • 本文会不断更斎ͼ主要变更及内容增加请参见文末变更记录

auto

nullptr

始终使用nullptr表示一个null指针|l不要用数?或者NULL宏,因ؓ它们也可以代表一个整数或者指针从而生歧义?/p>

Range for

Z范围的@环得按序讉K其中的每个元素变得非常方ѝ?/p>

Z以下两个原因Q尽可能使用autoQ首先,使用auto会避免重复声明编译器已经知道的类型?span class="Apple-style-span" style="font-family: verdana, 'courier new'; font-size: 13px; line-height: 21px; "> 
 
  
// C++98
  map<int,string>::iterator i = m.begin ();

  
// C++11

  auto i 
= begin (m);

其次Q当使用未知cd或者类型名UC易理解时使auto会更加便利,例如大多数的lambda函数QTODOQ?#8212;—你甚至不能简单的拼写出类型的名字?/span>

 
// C++98
  binder2nd< greater<int> > x = bind2nd ( greater<int>()Q?nbsp;42 );

  
// C++11

  auto x 
= [](int i) { return i > 42; };

需要注意,使用autoq不改变代码的含义。代码仍然是静态类型E译注Q,每个表达式的cd都是清晰和明的QC++11只是不需要我们重复声明类型的名字。一些h刚开始可能会x在q里使用autoQ因为感觉好像没有(重复Q声明我们需要的cd意味着会碰巧得C个不同的cd。如果你惌明确地进行一?em>强制cd转换Q没有问题,声明目标cd好了。然而大多数情况下,只要使用auto可以了Q几乎不会出现错误地拿到一个不同类型的情况Q即便出现错误,C++的强静态类型系l也会由~译器让你知道这个错误,因ؓ你正试图讉K一个变量没有的成员函数或是错误地调用了该函数?/p>

译注Q动态类型语aQdynamic typing languageQ是指类型检查发生在q行期间Qrun-timeQ的语言。静态类型语aQstatic typing languageQ是cd查发生在~译期间Qcompile-timeQ的语言?/p>

指针Q无delete

请始l用标准智能指针以及非占有原始指针(non-owning raw pointer)。绝不要使用占有原生指针(owning raw pointer)和delete操作Q除非在实现你自q底层数据l构q种见的情况下Q即使在此时也需要在 class 范围内保持完好的装Q。如果只能够知道你是另一个对象唯一的所有者,请用unique_ptr来表C唯一所有权QTODO)。一?#8221;new T”表达式会马上初始化另一个引用它的对象,通常是一个unique_ptr?br />



 
// C++11 Pimpl Idiom
  class widget {

  widget ();

  
~widget ();

  
private:

  
class impl;

  unique_ptr
<impl> pimpl;

  };

  
// in .cpp file

  
class impl {

  :::

  };

  widget::widget ()

  : pimpl ( 
new impl () )

  {

  }

  widget::
~widget () = default;
使用shared_ptr来表C共享所有权。推荐用make_shared来有效地创徏׃n对象?br />

 
// C++98
  widget* pw = new widget ();

  :::

  delete pw;

  
// C++11

  auto pw 
= make_shared<widget>();

使用 weak_ptr 来退出@环ƈ且表C可选性(例如Q实C个对象缓存)

  
// C++11
  class gadget;

  
class widget {

  
private:

  shared_ptr
<gadget> g; // if shared ownership

  };

  
class gadget {

  
private:

  weak_ptr
<widget> w;

  };

如果你知道另一个对象存在时间会更长久ƈ且希望跟t它Q用一个(非占有non-owning)原始指针?/span>

  
// C++11
  class node {

  vector
< unique_ptr<node> > children;

  node
* parent;

  
public:

  :::

  };

nullptr

始终使用nullptr表示一个null指针|l不要用数?或者NULL宏,因ؓ它们也可以代表一个整数或者指针从而生歧义?/p>

Range for

Z范围的@环得按序讉K其中的每个元素变得非常方ѝ?br />


  
// C++98
  for( vector<double>::iterator i = v.begin (); i != v.end (); ++i ) {

  total 
+= *i;

  }

  
// C++11

  
for( auto d : v ) {

  total 
+= d;

  }

非成员(nonmemberQ?begin ?end

始终使用非成员begin和endQ因为它是可扩展的ƈ且可以应用在所有的容器cd(container type)Q不仅仅是遵循了STL风格提供?.begin ()?.end ()成员函数的容器,甚至数组都可以用?/p>

如果你用了一个非STL风格的collectioncdQ虽然提供了q代但没有提供STL?.begin ()?.end ()Q通常可以个类型编写自q非成员begin和end来进行重载。这样你可以用STL容器的编E风格来遍历该类型。C++11标准提供了示?C数组是q样一个类型,标准同时为数l提供了begin和end?/p>


  vector
<int> v;
  
int a[100];

  
// C++98

  sort ( v.begin ()Q?nbsp;v.end () );

  sort ( 
&a[0], &a[0+ sizeof(a)/sizeof(a[0]) );

  
// C++11

  sort ( begin (v)Q?nbsp;end (v) );

  sort ( begin (a)Q?nbsp;end (a) );

Lambda 函数和算?/strong>

Lambda[TODO]是决定乾坤的因素Q它会你编写的代码变得更优雅、更快速。Lambda使得STL法的可用性提高了q?00倍。新q开发的C++函数库都是基于lambda可以用的前提Q例如,PPLQƈ且有些函数库甚至要求你编写lambda来调用函数库Q例如,C++ AMPQ?/p>

下面是一个快速示例:扑ֈv里面大于xq且于y的第一个元素。在C++11中,最单和q净的代码就是调用一个标准函数?br />


  
// C++98: write a naked loop (using std::find_if is impractically difficult)
  vector<int>::iterator i = v.begin (); // because we need to use i later

  
for( ; i != v.end (); ++i ) {

  
if*> x && *< y ) break;

  }

  
// C++11: use std::find_if

  auto i 
= find_if ( begin (v)Q?nbsp;end (v)Q?nbsp;[=](int i) { return i > x && i < y; } );

惌使用C++~写一个@环或者类似的新特性?不用着急;只要~写一个模板函敎ͼtemplate function)(函数库算法)Qƈ?em>几乎可以lambda当做语言Ҏ来使用Q与此同时会更加灉|Q因为它不是固定的语aҎ而是一个真正的函数库?/span>

  
// C#
  lock( mut_x ) {

   use x 

  }

  
// 不?nbsp;lambda 的C++11Q已l非常简zƈ且更灉|Q例如,可以使用时以及其他选项Q?/span>

  {

  lock_guard
<mutex> hold ( mut_x );

   use x 

  }

  
// C++11 with lambdas, and a helper algorithm: C# syntax in C++

  
// 使用?nbsp;lambda 的C++11可以带一个辅助算法:?nbsp;C++ 中?nbsp;C# 的文?br />
  
// Algorithm: template<typename T, typename F> void lock ( T& t, F f ) { lock_guard<T> hold (t); f (); }

  
lock( mut_xQ?nbsp;[&]{

   use x 

  });

ȝ悉lambda吧。你会大量用它Q不仅仅在C++?#8212;—它已l广泛应用于很多L的编E语a。一个开始的好去处请参考我在PDC2010的演讌Ӏ无处不在的 lambda?br />

Move / &&

Move被认为是copy的最佳优化,管它也使得其他事情成ؓ可能比如信息被{发?/p>



// C++98Q避?nbsp;copy 的替代方?/span>
  vector<int>* make_big_vector (); // 选择1: q回指针: 没有拯Q但不要忘记 delete

  :::

  vector
<int>* result = make_big_vector ();

  
void make_big_vector ( vector<int>& out ); // 选择2: 通过引用传? 没有拯Q但是调用者需要传入一个有名对?/span>

  :::

  vector
<int> result;

  make_big_vector ( result );

  
// C++11: move

  vector
<int> make_big_vector (); // 通常对于”被调用?callee)分配的空?#8220;也适用

  :::

  vector
<int> result = make_big_vector ();

Move语法改变了我们设计API的方式。我们可以更多地设计通过g递。ؓ你的cd启用move语法Q用时会比copy更有效?/p>

更多变化

q有更多CC++的特性。ƈ且我计划在未来编写更多深入C++11新特性以及其他特性的短文Q我们会知道更多q且喜欢上它?/p>

但目前,q是必须知道的新Ҏ。这些特性组成了CC++风格的核心,使得C++代码看v来和执行时像他们设计的那P你将会看到这些特性会出现在几乎每一D你看到或者编写的CC++代码中。ƈ且它们得现代C++更加q净、安全且快速,使得C++在未来的若干q仍然是我们产业的依靠?/p>

主要变更

2011-10-30:为Lambda增加C#lockCZ。重新组l智能指针首先介lunique_prt?/p>

文章Q?a target="_blank" style="color: #015fb6; text-decoration: none; ">伯乐在线







 



C加 2011-11-14 13:07 发表评论
]]>
þþþƷһ| þ97Ʒþþþþþò| þ޹vwww| þþƷž޾Ʒ| þþ㽶ۺϼձ| Ʒݾþþþ| þ99Ʒŷ| þþwww˳ɾƷ| 99þĻ| þ99Ʒþþþþhb| þԭavapp| þþ޾Ʒһ | þþƷһ | þþþAVۿ| ޹ƷþþþþԻ| ۺɫ77777þ| þþƷ| Ʒþ| þˬˬAV| þҹɫƷ| þ91ƷۺϹҳ| ۺϾþùһ鶹| 97þۺɫۺɫhd| þþþþþAv| þ޹ҹƷƬ | ˳վ999þþۺ| þþƷϵ| þù˾Ʒ鶹| ձþĻ| ھƷþù½| ƷþþþþþþþĻ| ճˮþ޾Ʒtv| þùɫavѿ| ɫۺϾþۺ| þþþþùƷŮ| 鶹wwwþ| ޹Ʒþþž| ݺݺɫۺϾþð| þӰԺҹƬ| ŷһþ| Ʒ˾þþ|