??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲最大天堂无码精品区,亚洲AV无码乱码在线观看裸奔,亚洲熟妇色自偷自拍另类http://m.tkk7.com/dongwq/category/23498.htmlq去理解的,现在未必理解? q去懂得的,重温必有新意? 整理q去Q整理现在。成q在,成就未来?/description>zh-cnWed, 21 Apr 2010 00:11:40 GMTWed, 21 Apr 2010 00:11:40 GMT60C++ placement new 用法举例zzhttp://m.tkk7.com/dongwq/archive/2010/04/20/318874.html强摩羯?/dc:creator>强摩羯?/author>Tue, 20 Apr 2010 09:15:00 GMThttp://m.tkk7.com/dongwq/archive/2010/04/20/318874.htmlhttp://m.tkk7.com/dongwq/comments/318874.htmlhttp://m.tkk7.com/dongwq/archive/2010/04/20/318874.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/318874.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/318874.htmlC++ placement new 用法举例zz
2009-12-17 16:16

在处理内存分配的时候,C++E序员会?/span>new操作W(operator newQ来分配内存Qƈ?/span>delete操作W(operator deleteQ来释放内存。这是一?/span>new操作W的例子?/span>

class CTest
{
     
/* 成员函数和成员数?/span> */
};

// . . . 代码

//
分配一个对?/span>
CTest * pTest = new Test;
// 分配一个有十个对象的数l?/span> (CTest 要有~省构造函敎ͼdefault constuctorQ?/span>)
CTest * p10Tests = new Test[ 10];

虽然q种写法在大多数时候都工作得很好,但还是有些情况下使用new是很烦h的,比如当你想重新分配一个数l或者当你想在预分配的内存上构造一个对象的时候?/span>

比如W一U情况,重新分配一个数l效率是很低的:

// 分配一个有10个对象的数组
CTest * pTests = new Test[ 10];
// . . .
//
假设现在我们需?/span>11个对?/span>
CTest * pNewTests = new Test[ 11];
// . . . 我们必须把原来的对象拯到新分配的内存中
for ( int i = 0; i < 10; i++)
     pNewTests[ i] = pTests[ i];
delete pTests;
pTests = pNewTests;

如果你想在预分配的内存上创徏对象Q用~省?/span>new操作W是行不通的。要解决q个问题Q你可以?/span>placement new构造。它允许你构造一个新对象到预分配的内存上Q?/span>

// buffer 是一?/span>void指针 (void *)
//
用方括号[] 括v来的部分是可选的
[CYourClass * pValue = ] new( buffer) CYourClass[( parameters)];

下面是一些例子:

#include <new>

class CTest
{
public:
     CTest()
     {}
     CTest( int)
     {}
    
/* 代码*/
};

int main(int argc, char* argv[])
{

     //
׃q个例子的目的,我们不考虑内存寚w问题
     char strBuff[ sizeof( CTest) * 10 + 100];
     CTest * pBuffer = ( CTest *)strBuff;

    
// ~省构?/span>
     CTest * pFirst = new(pBuffer) CTest;

    
// ~省构?/span>
     CTest * pSecond = new(pBuffer + 1) CTest;
    
    
// 带参数的构造;
     //
不理会返回的指针
     new(pBuffer + 2) CTest( 5);

    
// 带参数的构?/span>
     CTest * pFourth = new( pBuffer + 3) CTest( 10);

    
// ~省构?/span>
     CTest * pFifth = new(pBuffer + 4) CTest();

    
// 构造多个元素(~省构造)
     CTest * pMultipleElements = new(pBuffer + 5) CTest[ 5];
     return 0;
}

当你有自q内存~冲区或者在你实现自q内存分配{略的时候,placement new会很有用。事实上?/span>STL中广泛用了placement new来给容器分配内存Q每个容器类都有一个模版参数说明了构?/span>/析构对象时所用的分配器(allocatorQ?/span>

在?/span>placement new的时候,你要C以下几点Q?/span>

  • 加上头文?/span>#include <new>
  • 你可以用placement new构造一个数l中的元素?/span>
  • 要析构一个用placement new分配的对象,你应该手工调用析构函敎ͼq不存在一?/span>“placement delete”Q。它的语法如下:

pFirst->~CTest();
pSecond->~CTest();

前段事gQ我问过关于placement new的问题,一位仁兄讲了一些道理,他说道:

Q:栈上的对?注意,是类对象,charcd无需?后面q会提到)保证攑֜寚w地址? 

但是Q个人实验了一下,发现q不是这?br />
例如Q?br /> int main()
{
char c1 = 'A' ;
char c2 = 'B' ;
char c3 = 'C' ;
char c4 = 'D' ;
char c5 = 'E' ;

//-------- 验证q四个地址是否?nbsp;4 的倍数 --------------//
if ( ((int)(&c1)) % 4 == 0 )
cout << "c1:Yes" << endl ;

if ( ((int)(&c2)) % 4 == 0 )
cout << "c2:Yes" << endl ;

if ( ((int)(&c3)) % 4 == 0 )
cout << "c3:Yes" << endl ;

if ( ((int)(&c4)) % 4 == 0 )
cout << "c4:Yes" << endl ;

if ( ((int)(&c5)) % 4 == 0 )
cout << "c5:Yes" << endl ;

cout << (int)(&c1) << endl // 输出四个字符所在的地址Q输出结果都?nbsp;4 的倍数Q?br />  << (int)(&c2) << endl 
 << (int)(&c3) << endl 
 << (int)(&c4) << endl 
 << (int)(&c5) << endl ;
}
-----------------------------
上面的执行结果在VC下运行都?nbsp;4 的倍数
Q-Q-Q-Q-Q-Q-Q-

--> 问题1Q连栈上分配的空间地址都是 4 的倍数Q那p明系l分配的I间都是 4 的倍数吧?Q?

--> 问题2Q如果万一Q如果放一个对象的地址不是4的倍数Q那么会出现什么情况?Q可以给单说一下吗Q?br />
--> 问题3Q地址寚w的通用性?Q?
   Q-Q-Q-Q-Q-Q-Q?br />    E序1Q?br /> Class C1
{
int i ;
char c ;
} ;
cout << sizeof(C1) << endl ;// 输出l果Q?nbsp;8 Q是 4 的倍数Q?br />    E序2Q?br /> class C2
{
char c1 ;
char c2 ;
} ;
cout << sizeof(C2) << endl ;// 输出l果Q? Q?nbsp;上一个中charcd也给?个字节,怎么q个地方都给了一个字节?Q)
--> 问题4Q由上面的程? 引出下面的程?br /> class C2// sizeof(C2) =2 ,在VC实验下的l果Q不?nbsp;4
{
char c1 ;
char c2 ;
} ;
//----------用placement newҎ建立对象----------------
void *ptr = operator new(100) ;// 分配内存
C2 *POINTER = (C2*)ptr ;// cd转换
String *str1 = new (POINTER) C2() ;// 建立一C2对象
String *str2 = new (POINTER+1) C2() ;// 再徏立一个对?br /> String *str3 = new (POINTER+2) C2() ;// 再徏立一个对?br />
cout << (int)(str1) << endl// l果Q?608720Q?nbsp; ?的倍数Q?br />       << (int)(str2) << endl // l果Q?608722Q不?的倍数Q!Q?br />                      << (int)(str3) << endl ;// l果Q?608724Q不?的倍数Q!Q?br />


]]>
字符串拆分的中文处理问题zzhttp://m.tkk7.com/dongwq/archive/2010/04/19/318703.html强摩羯?/dc:creator>强摩羯?/author>Sun, 18 Apr 2010 17:47:00 GMThttp://m.tkk7.com/dongwq/archive/2010/04/19/318703.htmlhttp://m.tkk7.com/dongwq/comments/318703.htmlhttp://m.tkk7.com/dongwq/archive/2010/04/19/318703.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/318703.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/318703.html

字符串拆分的中文处理问题

容健行@2007q?/span>7?/span>

转蝲h明出?/span>

原文出处Q?a target="_blank">http://www.devdiv.net/home/space.php?uid=125&do=blog&id=365

概述Q?/font>

拆分一个字W串在程序中使用非常q泛Q特别是我们l常跟表格打交道的程序员们。所谓拆分字W串Q就是将一个字W串中间以某个(或某些)字符为分隔,拆分成多个字W串。如 std::string s = "abc | ddd | 中国";    如果以竖U?#8220;|”拆分Q可以将q个字符串拆分成三个字符丌Ӏ?/span>

当然字符串拆分还包括通过正则表达式来拆分Qؓ了简化问题,我们以单个字W做分隔的拆分,因ؓq种拆分用得最多。代码?/span>C++来讲解?/span>

问题Q?/font>

问题来源于实际,是之前我们组和其他组都有遇上的。先看一个例子,使用"|"拆分以下字符Ԍ看v来怎么数都是分?/span>48列,但我看到好几个版本的字符串拆分函数却报有49列:

"AGZGY1000004|200|刘瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓?/span>||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||"

原因分析Q?/font>

让我们先把以上字W串攑ֈUltraEdit中,q切换到16q制的编辑模式,看看它的~码?/span>

原因是原来的字符串拆分函数只是简单的查找“?#8221;Q编码ؓ0x7cQ?/span>,而没有考虑C文的处理Q源代码太多Q且有好几个版本Q这里略去)?/span>

?/span>boss中,c++E序使用的编码方式几乎全?/span>ansiQ而在ansi中,表示中文是用两个字符Q且W一个字W是一个大?/span>0x80的字W(字符的第一位ؓ1Q,W二个字WؓL字符。这里引起一个问题:

当我们要分割字符串时Q假如用"|"(0x7c)作ؓ分割W,当分析上面这个字W遇?/span>"?/span>"(~码?/span>0xad,0x7c)q个字符Ӟ会把它第二个字符作ؓ了分割符Q结果就多出了一列?/span>

解决ҎQ?/font>

问题原因扑ֈ了,重新写了一下字W串拆分函数Q?/span>SplitQ这里用的Ҏ是:扑ֈ分隔W后Q再向前查找字符看一下它前一个字W是否ؓ东亚文字的第一个字W编码(~码大于0x80Q?/span>

考虑C后支?/span>unicodeQ这里用了模板。以下可能不是最高效单的实现Q但如果以后遇上q种问题Q可以参考一下?/span>

#include "stdafx.h"

#include <stdio.h>

#include <tchar.h>

#include <iostream>

#include <string>

#include <vector>

#include <algorithm>

#include <fstream>

// unicode 分割{略

inline

    bool __SplitPolicy(

    const std::wstring& s,

    const std::wstring& splitchar,

    std::wstring::size_type& pos)

{

    pos = s.find_first_of(splitchar, pos);

    return pos != std::string::npos;

}

// ansi 分割{略

inline

    bool __SplitPolicy(

    const std::string& s,

    const std::string& splitchar,

    std::string::size_type& pos)

{

    pos = s.find_first_of(splitchar, pos);

    if (pos != std::string::npos)

    {

       // 如果前一个字W的W一位ؓ1Q且当前字符是在东亚文字的第二个字符Q?/span>

       // 则认字符是东亚字的其中一个字W,要蟩q,不作为分割符?/span>

       std::string::size_type i = 1;

       for (; i < pos; ++i)

       {

           if (!((char)(s[pos - i]) & 0x80)) // 判断W一位是否ؓ1。(0x80的二q制?10000000Q?/span>

              break;

       }

       if (!(i % 2)) // 看一下当前字W是否ؓ东亚文字的第二个字符

       {

           ++pos;

           __SplitPolicy(s, splitchar, pos);

       }

    }

    return pos != std::string::npos;

}

template<typename char_type> inline

    int Split(

    const std::basic_string<char_type>& s,

    const std::basic_string<char_type>& splitchar,

    std::vector<std::basic_string<char_type> >& vec)

{

    typedef std::basic_string<char_type>   string_t;

    typedef typename string_t::size_type   size_t;

    string_t tmpstr;

    size_t pos = 0, prev_pos = 0;

    vec.clear();

    while (__SplitPolicy(s, splitchar, pos))

    {

       tmpstr = s.substr(prev_pos, pos - prev_pos);

       vec.push_back(tmpstr);

       prev_pos = ++pos;

    }

    size_t len = s.length() - prev_pos;

    if (len > 0)

       vec.push_back(s.substr(prev_pos, len));

    return static_cast<int>(vec.size());

}

// ansi版本试

void testSplit()

{

    std::vector<std::string> vec;

    const std::string str = "AGZGY1000004|200|刘瓅瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||a";

    const std::string sp = "|";

    int count = Split(str, sp, vec);

    for (std::vector<std::string>::const_iterator it = vec.begin(); it != vec.end(); ++it)

       std::cout << *it << " ";

}

// unicode版本试

void testSplitW()

{

    std::vector<std::wstring> vec;

    const std::wstring str = L"AGZGY1000004|200|刘瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||";

    const std::wstring sp = L"|";

    Split(str, sp, vec);

    const char head[3] = {0xff, 0xfe, 0};

    const wchar_t line[3] = L" ";

    // 控制台输Z了unicode字符Q用输出到文g的方?/span>

    std::ofstream fileOut("C:/out.txt");

    fileOut.write(head, 2);

    for (std::vector<std::wstring>::iterator it = vec.begin(); it != vec.end(); ++it)

    {

       fileOut.write((const char*)it->c_str(), it->length() * 2);

       fileOut.write((const char*)line, 2);

    }

}

int main()

{

    testSplit();

    testSplitW();

}

参考:

1Q?a target="_blank">http://unicode.org/

2Q?/span>《谈谈Unicode~码Q简要解释UCS、UTF、BMP、BOM{名词?/span>



]]>
关于C++中文字符的处?/title><link>http://m.tkk7.com/dongwq/archive/2010/04/18/318627.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Sat, 17 Apr 2010 17:10:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2010/04/18/318627.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/318627.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2010/04/18/318627.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/318627.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/318627.html</trackback:ping><description><![CDATA[<h3><a >关于C++中文字符的处?/a></h3> <div id="wmsg8gw" class="blog_content"> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: red">一 引入问题</span></div> <div style="text-indent: 21pt; line-height: 20pt" align="left"><span style="font-size: 9pt">代码 wchar_t a[3]=L”中国”Q编译时出错Q出错信息ؓQ数l越界。但wchar_t 是一个宽字节cdQ数la的大应?个字节,而两个汉字的的unicode码占4个字节,再加上一个结束符Q最?个字节,所以应该不会越界。难道是~译器出问题了?</span></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: red">?解决引入问题所需的知?/span></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: red">   </span><span style="font-size: 9pt">主要需两方面的知识Q第一个ؓ字符其是汉字的~码Q以及语a和工L支持情况Q第二个是vc/c++中MutiByte Charater Set ?Wide Character Set有关内存分配的情?</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: red">?汉字的编码方式及在vc/c++中的处理</span></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">1.</span><span style="font-size: 9pt; color: blue">汉字~码方式的介l?/span> </div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">对英文字W的处理Q?位ASCII码字W集中的字符卛_满使用需求,且英文字W在计算Z的输入及输出也非常简单,因此Q英文字W的输入、存储、内部处理和输出都可以只用同一个编码(如ASCII码)?/span></div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">而汉字是一U象形文字,字数极多Q现代汉字中仅常用字有六、七千个Qd数高?万个以上Q,且字形复杂,每一个汉字都?韟뀁Ş、义"三要素,同音字、异体字也很多,q些都给汉字的的计算机处理带来了很大的困难。要在计机中处理汉字,必须解决以下几个问题Q首先是汉字的输入,卛_何把l构复杂的方块汉字输入到计算Z去,q是汉字处理的关键;其次Q汉字在计算机内如何表示和存储?如何与西文兼容?最后,如何汉字的处理l果从计机内输出? </span></div> <div style="text-indent: 15.75pt; line-height: 20pt" align="left"><span style="font-size: 9pt">为此Q必d汉字代码化,卛_汉字q行~码。对应于上述汉字处理q程中的输入、内部处理及输出q三个主要环节,每一个汉字的~码都包括输入码、交换码、内部码和字形码。在计算机的汉字信息处理pȝ中,处理汉字时要q行如下的代码{换:输入?#8594;交换?#8594;内部?#8594;字Ş码?/span></div> <div align="left"><span style="font-size: 9pt">(1)</span><span style="font-size: 9pt">输入码: 作用是,利用它和现有的标准西文键盘结合来输入汉字。输入码也称为外码。主要归为四c:</span> </div> <div align="left"><span style="font-size: 9pt">a)</span><span style="font-size: 9pt">      </span><span style="font-size: 9pt">数字~码Q数字编码是用等长的数字串ؓ汉字逐一~号Q以q个~号作ؓ汉字的输入码。例如,Z码、电报码{都属于数字~码?/span> </div> <div align="left"><span style="font-size: 9pt">b)</span><span style="font-size: 9pt">      </span><span style="font-size: 9pt">拼音码:拼音码是以汉字的读音为基的输入办法?/span> </div> <div align="left"><span style="font-size: 9pt">c)</span><span style="font-size: 9pt">      </span><span style="font-size: 9pt">字Ş码:字Ş码是以汉字的字Şl构为基的输入编码。例如,五笔字型码(王码Q?/span> </div> <div align="left"><span style="font-size: 9pt">d)</span><span style="font-size: 9pt">      </span><span style="font-size: 9pt">韛_Ş码:韛_Ş码是兼顾汉字的读韛_字Ş的输入编码?/span> </div> <div align="left"><span style="font-size: 9pt">(2)</span><span style="font-size: 9pt">交换码:用于汉字外码和内部码的交换。交换码的国家标准代号ؓGB2312-80?/span> </div> <div align="left"><span style="font-size: 9pt">(3)</span><span style="font-size: 9pt">内部码:内部码是汉字在计机内的基本表示形式Q是计算机对汉字q行识别、存储、处理和传输所用的~码。内部码也是双字节编码,国标码两个字节的最高位都置?1"Q即转换成汉字的内部码?/span> </div> <div align="left"><span style="font-size: 9pt">(4)</span><span style="font-size: 9pt">字Ş码:字Ş码是表示汉字字Ş信息Q汉字的l构、Ş状、笔划等Q的~码Q用来实现计机Ҏ字的输出Q显C、打华ͼ?/span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">2.VC</span><span style="font-size: 9pt; color: blue">中汉字的~码方式</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">     vc/c++</span><span style="font-size: 9pt">正是采用了GB2312内部码作为汉字的~码方式,因此vc/c++中的各种输入输出ҎQ如cin/wcin,cout/wcout,scanf/wsanf,printf/wprintf...都是ZGB2312的,如果汉字的内码不是这U编码方式,那么利用上述各种Ҏ׃会正的解析汉字?/span> </div> <div style="text-indent: 24pt; line-height: 20pt" align="left"><span style="font-size: 9pt">仔细观察ASCII字符表,从第161个字W开始,后面的字Wƈ不经ؓ用户所使用Q负g未用。GB2312~码方式充分利用q一Ҏ,?61-255Q?95~-1Q之间的数值空间作为汉字的标识码。既?55-161 = 94不能满汉字定w的要求,将每两个字Wƈ在一?即一个汉字占两个字节)Q显Ӟ94* 94 =8836基本上已l满了常用汉字个数的要求。计机处理字符Ӟ当连l处理到两个大与160(?95~-1)的字节时Q就认ؓq两个字节存放了一个汉字字W。可以用下面的DemoE序来模拟vc/c++中输出汉字字W的q程?/span></div> <div align="left"><span style="font-size: 9pt">    <span style="color: blue">unsigned</span> <span style="color: blue">char</span> input[50];</span></div> <div style="text-indent: 18pt" align="left"><span style="font-size: 9pt">cin>>input;</span></div> <div align="left"><span style="font-size: 9pt">    <span style="color: blue">int</span> flag=0;</span></div> <div align="left"><span style="font-size: 9pt">     <span style="color: blue">for</span>(<span style="color: blue">int</span> i =0 ;i < 50 ;i++)</span></div> <div align="left"><span style="font-size: 9pt">      {</span></div> <div align="left"><span style="font-size: 9pt">         <span style="color: blue">if</span>(input[i] > 0xa0 && input[i] != 0)</span></div> <div align="left"><span style="font-size: 9pt">          {</span></div> <div align="left"><span style="font-size: 9pt">              <span style="color: blue">if</span>(flag == 1)</span></div> <div align="left"><span style="font-size: 9pt">               {</span></div> <div align="left"><span style="font-size: 9pt">                    cout<<"chinese character"<<endl;</span></div> <div align="left"><span style="font-size: 9pt">                    flag = 0;</span></div> <div align="left"><span style="font-size: 9pt">               }</span></div> <div align="left"><span style="font-size: 9pt">              <span style="color: blue">else</span></span></div> <div align="left"><span style="font-size: 9pt">               {</span></div> <div align="left"><span style="font-size: 9pt">                    flag++;</span></div> <div align="left"><span style="font-size: 9pt">               }</span></div> <div align="left"><span style="font-size: 9pt">          }</span></div> <div align="left"></div> <div align="left"><span style="font-size: 9pt">         <span style="color: blue">else</span> <span style="color: blue">if</span>(input[i] == 0)</span></div> <div align="left"><span style="font-size: 9pt">          {</span></div> <div align="left"><span style="font-size: 9pt">              <span style="color: blue">break</span>;</span></div> <div align="left"><span style="font-size: 9pt">          }</span></div> <div align="left"><span style="font-size: 9pt">         <span style="color: blue">else</span> </span></div> <div align="left"><span style="font-size: 9pt">          {</span></div> <div align="left"><span style="font-size: 9pt">               cout<<"english character"<<endl;</span></div> <div align="left"><span style="font-size: 9pt">          }</span></div> <div style="text-indent: 24pt; line-height: 20pt" align="left"><span style="font-size: 9pt">}</span></div> <div style="text-indent: 24pt; line-height: 20pt" align="left"><span style="font-size: 9pt">输入Q?/span><span style="font-size: 9pt">Hello</span><span style="font-size: 9pt">中国 Q?#8220;中国”对应的GB2312内码为:214 208Q?85 250Q?/span> </div> <div style="text-indent: 24pt; line-height: 20pt" align="left"><span style="font-size: 9pt">输出Qenglish character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">english character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">english character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">english character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">english character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">chinese character</span></div> <div style="text-indent: 45pt; line-height: 20pt" align="left"><span style="font-size: 9pt">chinese character</span></div> <div align="left"></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">vc/c++</span><span style="font-size: 9pt">中的英文字符仍然采用ASCII~码方式。可以设惻I其他国家E序员利用vc/c++~写E序输入本国字符Ӟvc/c++则会采用该国的字W编码方式来处理q些字符?/span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">    </span><span style="font-size: 9pt">问题又生了Q韩国的vc/c++E序在中国的vc/c++上运行时Q如果没有相应的内码库,则对韩语字符的显C有可能出现q。我个h猜测Qvc安装E序中应该带有不同国家的内码库,q样一来肯定会占用很大的空间。如果所有的国家使用l一的编码方式,且所有的E序设计语言和开发工具都支持q种~码方式该多好!而现实中Q确实已l有q种~码方式了,且许多新的语a也都支持q种~码方式Q如Java、C#{,它就是下面的Unicode~码</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">3.</span><span style="font-size: 9pt; color: blue">新的内码标准---Unicode</span> </div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">Unicode</span><span style="font-size: 9pt">Q统一码、万国码、单一码)是一U在计算Z使用的字W编码。它为每U语a中的每个字符讑֮了统一q且唯一的二q制~码Q以满跨语a、跨q_q行文本转换、处理的要求?990q开始研发,1994q正式公布。随着计算机工作能力的增强QUnicode也在面世以来的十多年里得到普及。最新版本的 Unicode ?2005<span>q?</span><span>?1</span><span>?/span>推出的Unicode 4.1.0 。另外,5.0 Beta已于2005q?2?2日推出,以供各会员评仗?/span> </div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">Unicode </span><span style="font-size: 9pt">~码pȝ可分为编码方式和实现方式两个层次?/span> </div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">~码方式QUnicode 的编码方式与 ISO 10646 的通用字符集(Universal Character SetQUCSQ概늛对应Q目前的用于实用?Unicode 版本对应?UCS-2Q?6位的~码I间。也是每个字符占用2个字节。这LZ一共最多可以表C?216 个字W。基本满_U语a的用。实际上目前版本?Unicode 未填充满这16位编码,保留了大量空间作为特D用或来扩展?/span></div> <div style="text-indent: 18pt; line-height: 20pt" align="left"><span style="font-size: 9pt">实现方式QUnicode 的实现方式不同于~码方式。一个字W的 Unicode ~码是确定的。但是在实际传输q程中,׃不同pȝq_的设计不一定一_以及Z节省I间的目的,?Unicode ~码的实现方式有所不同。Unicode 的实现方式称为Unicode转换格式QUnicode Translation FormatQ简UCؓ UTFQ。如QUTF-8 ~码Q这是一U变长编码,它将基本7位ASCII字符仍用7位编码表C,占用一个字节(首位?Q。而遇C其他 Unicode 字符混合的情况,按一定算法{换,每个字符使用1-3个字节编码,q利用首位ؓ0?q行识别?/span></div> <div style="text-indent: 15.75pt; line-height: 20pt" align="left"><span style="font-size: 9pt">Java</span><span style="font-size: 9pt">与C#语言都是采用Unicode~码方式Q在q两U语a中定义一个字W,在内存中存放的就是这个字W的两字节Unicode码。如下所C:</span> </div> <div style="text-indent: 15.75pt; line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">char</span><span style="font-size: 9pt"> a='</span><span style="font-size: 9pt">?;<span>     => </span>内存中存攄Unicode码ؓQ?5105</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">4.</span><span style="font-size: 9pt; color: blue">内码的相互{?/span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">(1)vc</span><span style="font-size: 9pt">中的实现Ҏ</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">   </span><span style="font-size: 9pt">利用Windowspȝ提供的APIQ?/span><strong><span style="font-size: 9pt">::MultiByteToWideChar</span></strong><strong><span style="font-size: 9pt">?/span></strong><strong><span style="font-size: 9pt">::WideCharToMultiByte</span></strong> </div> <div style="text-indent: 17.7pt; line-height: 20pt" align="left"><strong><span style="font-size: 9pt">::MultiByteToWideChar</span></strong><strong><span style="font-size: 9pt">Q?/span></strong><span style="font-size: 9pt">实现当前码到</span><span style="font-size: 9pt">Unicode</span><span style="font-size: 9pt">码的转换Q?/span> </div> <div style="text-indent: 17.7pt; line-height: 20pt" align="left"><strong><span style="font-size: 9pt">::WideCharToMultiByte</span></strong><strong><span style="font-size: 9pt">Q?/span></strong><span style="font-size: 9pt">实现</span><span style="font-size: 9pt">Unicode</span><span style="font-size: 9pt">码到当前码的转换Q?/span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">(2)Java</span><span style="font-size: 9pt">中的实现Ҏ</span> </div> <div style="text-indent: 4.45pt; line-height: 20pt" align="left"><strong><span style="font-size: 9pt">    String vcString=new String(javaString.getBytes("UTF-8"),"gb2312");</span></strong></div> <div style="text-indent: 17.8pt; line-height: 20pt" align="left"><span style="font-size: 9pt">java</span><span style="font-size: 9pt">的编码应该是</span><span style="font-size: 9pt">UTF-8</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">(3)C#</span><span style="font-size: 9pt">中的实现Ҏ</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">    ??</span></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: red">?vc中的MutiByte Charater Set ?Wide Character Set</span></div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt; color: blue">1.MultiByte Charater Set</span><span style="font-size: 9pt; color: blue">方式</span> </div> <div style="line-height: 20pt" align="left"><span style="font-size: 9pt">   </span><span style="font-size: 9pt">q种方式以按字节为单位存攑֭W,卛_果一个字W码Z字节Q则在内存中占两字节Q字W码Z字节Q就占一字节。例如,字符?#8220;中国abc”的编码ؓQ中(0xd6?xd0)、国(0xb9?xfa)、a(0x61)、b(0x62)、c(0x63)、\0(0x00)Q就存ؓ如下方式Q?/span> </div> <div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fishinthewind/Win_1.bmp" /></div> <div></div> <div></div> <div> <div style="text-indent: 13.5pt; line-height: 18pt"><span style="font-size: 9pt">对应的类型,Ҏ有:</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">char</span><span style="font-size: 9pt">、scanf、printf、cin、cout …</span> </div> <div style="line-height: 18pt"> <div style="line-height: 18pt"><span style="font-size: 9pt; color: blue">2.Wide Character Set</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt; color: blue"><span style="font-size: 9pt"><font color="#000000">q种方式是以两字节ؓ单位存放字符Q即如果一个字W码Z字节Q则在内存中占四字节Q字W码Z<span style="font-size: 9pt">字节Q就占两字节。例如,字符?#8220;中国<span>abc</span>”存为如下方式:</span></font></span></span></div> <div style="line-height: 18pt"><span style="font-size: 9pt; color: blue"><span style="font-size: 9pt"><font color="#000000"></font></span></span></div> <div style="line-height: 18pt"><span style="font-size: 9pt; color: blue"><span style="font-size: 9pt"><font color="#000000"></font></span></span></div> </div> </div> <div><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fishinthewind/win_2.bmp" /></div> <div></div> <div></div> <div><span style="font-size: 9pt">对应的类型,Ҏ有:</span></div> <div> <div style="line-height: 18pt"><span style="font-size: 9pt">wchar_t</span><span style="font-size: 9pt">、wscanf、wprintf、wcin、wcout …</span> </div> <div style="text-indent: 13.5pt; line-height: 18pt"><span style="font-size: 9pt">造成上面存储方式的根本原因在于,<span style="color: red">wchar_t</span><span style="color: red">cd其实是一个unsigned short cd</span>。如Q存储上面字W串的数l的定义为:wchar_t buffer[8] {h于unsigned short buffer[8].而所有以字母w开头的Ҏ也都是以unsigned shortcd,即两字节为单位来处理字符Q因此,存储在wchar_tcd数组中的字符串无法用cout昄Q只能用wcoutҎ来显C?/span></div> <div style="text-indent: 13.5pt; line-height: 18pt"><span style="font-size: 9pt">׃Unicode码也是采用两个字节,因此Wide Character Set方式能够很好的支持Unicode码的存储Q但是在vc的环境下要将一个Unicode码存入两字节而不是四字节内存中,必须通过上面的API函数</span><strong><span style="font-size: 9pt">::MultiByteToWideChar</span></strong><strong><span style="font-size: 9pt">?/span></strong><span style="font-size: 9pt">首先Q将当前的编码{换ؓUnicode码,然后Q将每个字符的Unicode码放入每一个wchar_tcd的变量中。以下是一个实例代码:</span> </div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt; color: blue">char</span><span style="font-size: 9pt"> input[50];</span> </div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt">cin>>input;</span></div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt; color: blue">int</span><span style="font-size: 9pt"> size;</span> </div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt">size=::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,NULL,0);</span></div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt; color: blue">if</span><span style="font-size: 9pt">(size==0)</span> </div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt">     <span style="color: blue">return</span> -1;</span></div> <div style="line-height: 18pt" align="left"><span style="font-size: 9pt; color: blue">wchar_t</span><span style="font-size: 9pt"> *widebuff=<span style="color: blue">new</span> <span style="color: blue">wchar_t</span>[size];</span> </div> <div style="line-height: 18pt"><span style="font-size: 9pt">::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,widebuff,size);</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">输入Q中国abc</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">Debug</span><span style="font-size: 9pt">断点调试Q?/span> </div> <div style="line-height: 18pt"><span style="font-size: 9pt">size==6</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">数组widebuff[0-size]?2字节Q存放了6个字W的Unicode码,码gؓQ?/span></div> <div style="text-indent: 9pt; line-height: 18pt"><span style="font-size: 9pt">?0x4e2d) ?0x56fd) a(0x0061) b(0x0062) c(0x0063) d(0x0000)</span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">q时Q数l的大小size{于输入的字W个数加上一个结束符Q符合我们的惌?/span></div> <div style="line-height: 18pt"><span style="font-size: 9pt; color: red">?引入问题的错误分?/span></div> <div style="line-height: 18pt"><span style="font-size: 9pt">(1) </span><span style="font-size: 9pt">没有理解~译器中的编码方?/span> </div> <div style="line-height: 18pt"><span style="font-size: 9pt">    </span><span style="font-size: 9pt">虽然vc/c++中汉字的~码占两个字节,但ƈ不是Unicode码,是GB2312码?/span> </div> <div style="line-height: 18pt"><span style="font-size: 9pt">(2) </span><span style="font-size: 9pt">没有理解MutiByte Charater Set ?Wide Character Set的存储原则;</span> </div> <div><span style="font-size: 9pt">    </span><span style="font-size: 9pt">在vc/c++中,“中国”按char[5]来对待,而wchar_t a[3]实际上是三个unsigned shortcd的变量,因此赋值时会越界?/span></div> </div> </div><img src ="http://m.tkk7.com/dongwq/aggbug/318627.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2010-04-18 01:10 <a href="http://m.tkk7.com/dongwq/archive/2010/04/18/318627.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gameloft??http://m.tkk7.com/dongwq/archive/2010/04/17/318576.html强摩羯?/dc:creator>强摩羯?/author>Fri, 16 Apr 2010 17:38:00 GMThttp://m.tkk7.com/dongwq/archive/2010/04/17/318576.htmlhttp://m.tkk7.com/dongwq/comments/318576.htmlhttp://m.tkk7.com/dongwq/archive/2010/04/17/318576.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/318576.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/318576.html//gameloft W试?br /> /*
1、RGBD{灰度值对32位整数取RQGQB对应?位ƈ加权合成?br /> 2、求一个字W串中出现频率最高的字符。字W范围ƈ涡有说明Q通常?br /> 指ASCII字符集,可是当时考虑复杂了,于是惛_了stl的map来做?br /> l果没有写完。就交了?
*/
#include<iostream>

using namespace std;
#define CHARNUM 256 
//计算一个串最出现频率最高的字符

char mostFreq(const char* str)
{
 int freq[CHARNUM]= {0};
 int firstPos[CHARNUM] = {0};
 int pos = 0;
 const char* p = str;
 while( *p != '\0')
 {
  if(freq[*p] == 0)
  {
   firstPos[*p] = pos; 
  }
  freq[*p++]++;
   pos++;
  }
  int maxF = -1;
  int ch = '\0';
  for(int i = 1;i < 256;i++)
  {
   if( freq[i] > maxF)
   {
    ch = i;
   maxF = freq[i];
   }
   if( freq[i] == maxF)
   {
    if( firstPos[i] < firstPos[ch])
    {
     ch = i; 
    }
   }    
  }
  cout<<" maxF ="<<maxF<<endl;
 
  return (char)ch;
}
 
int main()
{
 int* a[9][4][5];
 
 
 int b = a[5] - a[3];
 cout<<"b = "<<b<<endl;
 
 int* c[3];
 
 char * str = "aabyebbdfdf 1`5454545$$$#$#$2788kldef";
 
 char ch;
 ch = mostFreq( str);
 
 cout<<"ch = " <<ch<<endl;
}
4.l出一个CThing cȝ源代码让分析Q其中有三个语句要求解释语句作用?br /> 一个填I,分析时有点忙了,应该一个函C个函数的分析Q或怼有清晰思\?br /> 各个类的名U和功能整理下会理出些思\?br /> 5、给出strcpy的源代码让说明其功能Qƈ指出参数讄上只一人错?br /> 6、给Z个将整数i转换?q制的方法,要求对其q行改进?br /> src:
void count(int i, char* str)
{
     map[
 sorry, 记忆不清楚了

7、给几个名词让解释placement new,ARM, GCC, android, q有一人?Q?br />  8、英文解释题目。第一个还好。第二个说游戏加速的
 
 increment  ...update frame , ??q词词认识,放一赯不出来表CZ?br />  意?



]]>
C++一些用法整?/title><link>http://m.tkk7.com/dongwq/archive/2010/04/16/318481.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Fri, 16 Apr 2010 02:31:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2010/04/16/318481.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/318481.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2010/04/16/318481.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/318481.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/318481.html</trackback:ping><description><![CDATA[     摘要:   1   2   3   4#include<cstdio>   5#include<iostream>   6#include<cstdlib>   7#include<typeinfo>&nbs...  <a href='http://m.tkk7.com/dongwq/archive/2010/04/16/318481.html'>阅读全文</a><img src ="http://m.tkk7.com/dongwq/aggbug/318481.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2010-04-16 10:31 <a href="http://m.tkk7.com/dongwq/archive/2010/04/16/318481.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSingleList的类实现Q可以丰富v?/title><link>http://m.tkk7.com/dongwq/archive/2010/04/16/318480.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Fri, 16 Apr 2010 02:30:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2010/04/16/318480.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/318480.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2010/04/16/318480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/318480.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/318480.html</trackback:ping><description><![CDATA[     摘要:   1   2   3// realize a SingleList class   4/**//*   5实现Ҏ   6add()   7add2Head(dd);   8del ...  <a href='http://m.tkk7.com/dongwq/archive/2010/04/16/318480.html'>阅读全文</a><img src ="http://m.tkk7.com/dongwq/aggbug/318480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2010-04-16 10:30 <a href="http://m.tkk7.com/dongwq/archive/2010/04/16/318480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>指向指针的引?/title><link>http://m.tkk7.com/dongwq/archive/2009/04/15/265844.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Wed, 15 Apr 2009 13:03:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2009/04/15/265844.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/265844.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2009/04/15/265844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/265844.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/265844.html</trackback:ping><description><![CDATA[Q*君子da而过其行Q*<br /> <br /> typedef   int*   pint; <br /> typedef   pint*   ppint; <br /> void   func(ppint   &x) <br /> { <br />  x   =   new   int*; <br />  *x=   new   int(32); <br /> } <br /> //使用Ҏ<br /> <p> int   **p=0; <br />  func(p); <br />  cout<<(**p)<<endl; </p> <p> int *pV;<br />  pV =  new int(2);  //q里注意与在cpp中与java中语法的差异<br />  cout<<"PV = "<<(*pV)<<endl;</p>  int ival = 1024; <br />  int *pi = &ival; <br />  int* &ptrVal2 = pi;<img src ="http://m.tkk7.com/dongwq/aggbug/265844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2009-04-15 21:03 <a href="http://m.tkk7.com/dongwq/archive/2009/04/15/265844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz泛型~程Q源赗实C意义http://m.tkk7.com/dongwq/archive/2009/01/04/249663.html强摩羯?/dc:creator>强摩羯?/author>Sat, 03 Jan 2009 16:28:00 GMThttp://m.tkk7.com/dongwq/archive/2009/01/04/249663.htmlhttp://m.tkk7.com/dongwq/comments/249663.htmlhttp://m.tkk7.com/dongwq/archive/2009/01/04/249663.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/249663.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/249663.html泛型~程Q源赗实C意义
 By 刘未?C++的罗宫(http://blog.csdn.net/pongba)(d12月《程序员》的U稿)
(以前也写q一相关的文章Q?/span>Generic Programming - What Are You, anyway? )
 Z么泛?/span>
泛型~程Q?/span>Generic ProgrammingQ最初提出时的动机很单直接:发明一U语a机制Q能够帮助实C个通用的标准容器库。所谓通用的标准容器库Q就是要能够做到Q比如用一?/span>Listcd放所有可能类型的对象,q样的事情;熟悉一些其它面向对象的语言的h应该知道Q如Java里面q是通过?/span>List里面存放Object引用来实现的?/span>Java的单根承在q里起到了关键的作用。然而单根承对C++q样的处在语a铑ֺ层的语言却是不能承受之重。此外用单根承来实现通用容器也会带来效率和类型安全方面的问题Q两者都?/span>C++的理念不相吻合?/span>
 
于是C++另谋他法——除了单根承之外,另一个实现通用容器的方案就是?#8220;参数化类?#8221;。一个容器需要能够存放Q何类型的对象Q那q脆把q个对象的类?#8220;?#8221;出来Q参数化?/span>[1]Q?/span>
 
template<class T> class vector {
 T* v;
 int sz;
public:
 vector(int);
 T& operator[](int);
 T& elem(int i) { return v[i]; }
 // ...
};
 
一般来说看到这个定义的时候,每个人都会想?/span>C的宏。的,模板和宏在精上的确有相仿之处。而且的确Q也有h使用C的宏来实现通用容器。模板是一个定义里面的cd参数化出来,而宏也可以做到参数化cd。甚xU意义上可以说宏是模板的集——因为宏不仅可以参数化类型,宏实质上可以参数化一切文本,因ؓ它本来就是一个文本替换工兗然而,跟模板相比,宏的最大的~点是它ƈ不工作在C++的语法解析层面,宏是由预处理器来处理的,而在预处理器的眼里没?/span>C++Q只有一堆文本,因此C++的类型检查根本不起作用。比如上面的定义如果用宏来实玎ͼ那么q你传q去?/span>T不是一个类型,预处理器也不会报错;只有{到文本替换完了Q到C++~译器工作的时候才会发C堆莫名其妙的cd错误Q但那个时候错误就已经到处都是了。往往最后会抛出一堆吓人的~译错误。更何况宏基本无法调试?/span>
 
?/span>1
实际上,q有一U实现通用容器的办法。只不过它更p糕Q它要求M能存攑֜容器内的cd都承自一个NodeBaseQNodeBase里面有pre和next指针Q通过q种方式Q就可以Q意类型链入一个链表内了。但q种方式的致命缺Ҏ(1)它是侵入性的Q每个能够放在该容器内的cd都必ȝ承自NodeBase基类?2)它不支持基本内徏cdQint、double{)Q因为内建类型ƈ不,也不能承自NodeBase。这q姑且不说它是类型不安全的,以及效率问题?/div>
 
我们再来看一看通用法Q这是泛型的另一个动机。比如我们熟悉的C?/span>qsortQ?/span>
 
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
 
q个法有如下几个问题:
 
1.      cd安全性:使用者必自行保?/span>base指向的数l的元素cd?/span>compar的两个参数的cd是一致的Q用者必自行保?/span>size必须是数l元素类型的大小?/span>
2.      通用性:qsort对参数数l的二进制接口有严格要求——它必须是一个内存连l的数组。如果你实现了一个y妙的、分D连l的自定义数l,没法?/span>qsort了?/span>
3.      接口直观性:如果你有一个数l?/span>char* arr = new arr[10];那么该数l的元素cd其实已l?#8220;透露”了它自己的大。然?/span>qsort把数l的元素cdl?#8220;void”掉了Q?/span>void *baseQ,于是丢失掉了q一信息Q而只能让调用Ҏ动提供一?/span>size。ؓ什么要把数l类型声明ؓvoid*Q因为除此之外别无它法,声明ZQ意一个类型的指针都不妥(compar的参数类型也是如此)?/span>qsortZ通用性,把类型信息丢掉了Q进而导致了必须用额外的参数来提供类型大信息。在q个特定的算法里问题q不明显Q毕竟只多一?/span>size参数而已Q但一旦涉及的cd信息多了hQ其接口的可伸羃性(scalabilityQ问题和直观性问题就会逐渐昄?/span>
4.      效率Q?/span>compar是通过函数指针调用的,q带来了一定的开销。但跟上面的其它问题比v来这个问题还不是最严重的?/span>
 
泛型~程
泛型~程最初诞生于C++中,?/span>Alexander Stepanov[2]?/span>David Musser[3]创立。目的是Z实现C++?/span>STLQ标准模板库Q。其语言支持机制是模板Q?/span>TemplatesQ。模板的_其实很简单:参数化类型。换句话_把一个原本特定于某个cd的算法或cd中的cd信息抽掉Q抽出来做成模板参数T。比?/span>qsort泛化之后变成了Q?/span>
 
template<class RandomAccessIterator, class Compare>
void sort(RandomAccessIterator first, RandomAccessIterator last,
        Compare comp);
其中firstQ?/span>lastq一对P代器代表一个前闭后开区间QP代器和前开后闭区间都是STL的核心概cP代器建模的是内徏指针的接口(解引用、递增、递减{)、前开后闭区间是一个简单的数学概念Q表CZfirstQ含firstQ到lastQ不?/span>lastQ的区间内的所有元素。此外,comp是一个仿函数Q?/span>functorQ。仿函数也是STL的核心概念,仿函数是建模的内建函数的接口Q一个仿函数可以是一个内建的函数Q也可以是一个重载了operator()的类对象Q只要是支持函数调用的语法Ş式就可成Z个仿函数?/span>
 
通过操作W重载,C++允许了自定义cdh跟内建类型同L使用接口Q又通过模板q样的参数化cd机制Q?/span>C++允许了一个算法或cd义,能够利用q样的接口一致性来对自w进行泛化。例如,一个原本操作内建指针的法Q被泛化为操U一切P代器的算法。一个原本用内建函数指针的法Q被泛化够接受一切重载了函数调用操作W(operator()Q的cd象的法?/span>
 
让我们来看一看模板是如何解决上面所说的qsort的各个问题的Q?/span>
 
1.      cd安全性:如果你调?/span>std::sort(arr, arr + n, comp);那么comp的类型就必须要和arr的数l元素类型一_否则~译器就会帮你检查出来。而且comp的参数类型再也不?/span>const void*q种不直观的表示了,而是可以直接声明为对应的数组元素的类型?/span>
2.      通用性:q个刚才已经说过了。泛型的核心目的之一是通用性?/span>std::sort可以用于一切P代器Q其compare函数可以是一切支持函数调用语法的对象。如果你惌?/span>std::sort用在你自q容器上的话,你只要定义一个自qq代器类Q严格来说是一个随问P代器Q?/span>STL对P代器的访问能力有一些分c,随机讉Kq代器具有徏模的内徏指针的访问能力)Q如果需要的话,再定义一个自q仿函数类卛_?/span>
3.      接口直观性:?/span>qsort相比Q?/span>std::sort的用接口上没有多余的东西,也没有不直观?/span>size参数。一个有待排序的区间Q一个代表比较标准的仿函敎ͼ仅此而已[4]?/span>
4.      效率Q如果你传给std::sort?/span>compare函数是一个自定义?/span>operator()的仿函数。那么编译器p够利用类型信息,对该仿函数?/span>operatpr()调用直接内联。消除函数调用开销?/span>
 
动态多态与静态多?/span>
泛型~程的核心活动是抽象Q将一个特定于某些cd的算法中那些cd无关的共性抽象出来,比如Q在STL的概念体p里面,你是一个数l还是一个链表,反正都是一个区_q就是一层抽象。管你是一个内建函数还是一个自定义c,反正都是一?/span>CallableQ可调用Q的对象Q在C++里面通过仿函数来表示Q,q就是一层抽象。泛型编E的q程是一个不断将q些抽象提升Q?/span>liftQ出来的q程Q最l的目的是Ş成一个最大程度上通用的算法或cR?/span>
 
有h肯定会问Q既然同是抽象,那ؓ什么不用基于多态的面向对象抽象呢?比如STL?/span>std::for_eachQ用Java的多态机制也可以解决Q?/span>
 
interface IUnaryFun
{
void invoke(Object o);
}
 
interface IInputIter
{
IInputIter preIncrement();
boolean equals(IInputIter otherIter);
… // other methods
}
 
IUnaryFun for_each(IInputIter first, IInputIter last, IUnaryFun func)
{
 for(;!first.equals(last); first.preIncrement())
func.invoke(*first);
 return func;
}
 
其实Q这里最主要的原因很单,效率。面向对象的多态引入了间接调用。当Ӟq不是说间接调用不好Q有些时候,比如实需要运行期多态的时候,只能诉诸l承q样的手Dc但当能够利用编译期cd信息的时候,Z么要付出不必要的间接调用开销呢?比如q里?/span>for_eachQ利用接口来实现光用性,׃Z所谓的“抽象惩罚”Q?/span>abstraction penaltyQ。?/span>C++的模板,是Z消除q样的抽象惩|。利用模板编写的std::for_eachQ对于每一个特定的参数cdl合都有一个独立的Q最高效的实例化版本Q就跟你手写一个特定于q些cd的专门的for_each法一?/span>[5]。于是抽象惩|消׃Q而这也正?/span>C++模板库能够真正被工业界广泛用?/span>C++最擅长的领域(重视效率的领域)的重要原因之一?/span>
 
另一斚wQ对于每一l参数类型组合实例化一个版本出来的做法增加了代码空_q是一个典型的以空间换旉的例子,不过对于一门静态ƈq求效率的语a来说Q这个代码空间的开销反正也是必不可少的,因ؓ即便你手动ؓ各种不同的参数类型组合编写特定的法版本的话Q也是付ZL代码I间开销Q而且q顺便违反了DRY原则[6]。此外,׃在抽象的时候不用L着要徏立的接口Q所以泛型算法编写v来也更ؓ直观?/span>
 
C++泛型的另一个好处就是,跟面向对象编E的Zl承和虚函数的运行时多态机制不同,C++模板是非侵入性的。你不需要让你的cȝ承自某个特定的接口才能用于某个算法,只要支持特定的语法接口就行了Q比如只要支?/span>begin()调用Q。这也被UCؓl构一致性(Structural ConformanceQ,意即只要语法l构一致即可。而另一斚wQ基于接口承的面向对象多态则必须要显式地声明l承自一个接口,q就是所谓的名字一致性(Named ConformanceQ?/span>
 
当然Q泛型支持的静态多态和虚函数支持的动态多态ƈ没有ME度上绝对的优劣之分。它们适用于不同的场合。当cd信息可得的时候,利用~译期多态能够获得最大的效率和灵zL。当具体的类型信息不可得Q就必须诉诸q行期多态了?/span>Bjarne Stroustrup曄用了一个典型的例子来澄清这个区别:
 
std::vector<Shape*> v;
… // fill v
std::for_each(v.begin(), v.end(), std::mem_fun(&Shape::draw));
 
q里Q?/span>v里面到底来会存放什么类型的ShapeQ编译期无法知道Q因而必L助于动态多态。另一斚wQ编译器倒的知道它们都l承?/span>ShapeQ利用这仅有的静态类型信息,我们使用了泛型算?/span>std::for_each和泛型容?/span>std::vector。这里尤其值得注意的是for_each的静态多态行为:for_each只有一份模板实玎ͼ然而根据传l它的第三个参数Q本例中?/span>std::mem_fun(&Shape::draw)Q的不同Q?/span>for_each的行Z不同Q这里最l被for_each调用的是Shape::drawQ但实际上你可以包装M函数Q只要这个函数接受一?/span>Shape*型的参数Q,for_eachq种“行ؓ不同”是发生在~译期的Q所以是静态多态?/span>
 
前面说过Q模板与接口l承比较Q模板是非R入的。这?/span>C++泛型与面向对象的多态机制的本质区别之一。但实际上,面向对象未必意味着一定要用接口来实现动态的多态。一些动态类型的脚本语言Q如RubyQ它的多态机制就既是q行期(动态)的,又是非們օ性的Q不用通过l承自某个特定的接口来达到复用)。h们把q个叫做Duck Typing[7]。如果不是因为效率问题,其实q样的多态机制才是最直观的,从用方面来_它既有非侵入性,又没有只能工作在~译期的限制。但效率臛_在可见的来、在某些领域仍是一个顾虑。因此像C++q种区分~译期和q行期多态的语言Q仍有其独特的优ѝ?/span>
 
此外Q泛型编E的cd安全优势也让它从C++走入了其它主的静态类型语a当中Q尤其是C家族?/span>Java?/span>C#Q在前几q相l接Ux型?/span>
 
特化Q图灵完备性,元编E?/span>
C++的模板是支持特化的,q就l了它实现编译期控制l构的可能性,q而带来了一个图灵完备的子语a。模板特化的引入原本只是Z效率目的——针对不同的cd提供不同的实现。但后来却被发现能够实现~译期的if/else和递归{控制结构?/span>
 
模板元编E最初由Erwin Unruh?/span>1994q的一ơ会议上提出Q当时他写了一个程序,在编译错误里面打印出一个素数序列。这个事件在C++历史上的C׃佛哥伦布发现新大陆。用Bjarne Stroustrup的话来说是当时他当时和其他几个得太奇了。实际上Q这个事情正标志?/span>C++模板pȝ的图灵完备性被发现Q后?/span>Todd Veldhuizen写了一?/span>paperQ用C++模板构徏了一个元囄机,从而第一ơ系l证明了C++模板的图灵完备性。接下来的事情就理成章了——一?/span>ad hoc的模板元~程技巧不断被发掘出来Q用于徏造高效、高适应性的通用lg。最l,David Abrahams~写?/span>boost库中的基本组件之一Q?/span>Boost.MPL库?/span>Boost.MPL以类型和~译期常量ؓ数据Q以模板特化为手D,实现了一个编译期?/span>STL。你可以看到常见?/span>vectorQ你可以看到transform法Q只不过法操纵的对象和容器存放的对象不再是q行期的变量或对象,而是~译期的cd和常量。想知道模板元编E是如何用在库构Z的,可以打开一?/span>Boost的子库(比如Boost.Tuple?/span>Boost.VariantQ看一看?/span>
 
然而,毕竟C++的模板元~程是一门被发现而不是被发明的子语言。一斚wQ它在构建泛型库的时候极其有用。然而另一斚wQ由于它q语言设计初始时考虑在内的东西,所以不仅在语法上面昑־不那?/span>first-classQ比较笨拙)Q更重要的是Q由于本不是一?/span>first-class的语aҎ,所?/span>C++~译器ƈ不知?/span>C++元编E的存在。这意味着Q比如对下面q样一个编译期?/span>if/else设施[8]Q?/span>
 
template<bool b, class X, class Y>
struct if_ {
 typedef X type; // use X if b is true
};
template<class X, class Y>
struct if_<false,X,Y> {
typedef Y type; // use Y if b is false
};
 
typedef if_<(sizeof(Foobar)<40), Foo, Bar>::type type;
 
~译器ƈ没有真的去进?/span>if/else的分支选择Q而是按部q毫不知情地进行着模板的特化匹配。如果遇?/span>Boost.MPLq样的模板元~程非常重的库,׃严重拖篏~译速度Q编译器q行了一重一重的特化匚wQ实例化了一个又一个的模板实例Q就是ؓ了去获取里面定义的一?/span>typedefQ完了之后中间所有实例化出来的模板实例类型全都被丢弃[9]?/span>
 
模板元编E最全面深入的介l是Boost.MPL库的作?/span>David Abrahams的?/span>C++ Template Metaprogramming》,其中的样章(W三章)[10]Ҏ板元~程作了一个非帔R屋徏瓴的概览[11]?/span>
 
关于模板元编E,需要提醒的是,它ƈ不属?#8220;大众技?#8221;。日常编E中极少需要用到元~程技巧。另一斚wQ?/span>C++模板里面有大?/span>ad hoc的技巧,如果一头扎q去的话Q很Ҏ只见树木不见林Q所以需要提醒初学者的是,即便要学习,也要时刻保持“高度”Q始l记得元~程的意义和目的Q这h不至于迷失在无穷无尽的语al节中?/span>
 
C++09——进?/span>
泛型~程?/span>C++中取得了工业E度上的成功Q得益于光效性和通用性。但同时Q在l过了近十年的用之后,C++模板Q这个作?/span>C++实现泛型的机制的~点也逐渐暴露出来。比如其中对于初学者最严重的一个问题就是在使用一个模板库时常帔R到无法理解的~译错误Q动辄长达上K字节。这些编译错误很Ҏ把一个初学者吓走。究其本质原因,Z么编译器会报Zo人难以卒ȝ~译错误Q是因ؓ在编译器的眼里,只有cdQ而没?#8220;cd的类?#8221;。比如说QP代器是一个类型的cdQ?/span>C++里面也把它称?#8220;概念”Q?/span>ConceptQ。例如,std::sort要求参数必须是随问P代器Q如果你一不小心给了它一个非随机讉K的P代器Q那么编译器不是抱?#8220;嘿!你给我的不是随机讉Kq代?#8221;Q而是抱怨找不到某某重蝲操作W(典型的比?/span>operator+(int)Q。因为在~译器眼里,没有“q代?#8221;q么个概念,q个概念只存在于E序员脑子里?/span>STL的文档里。ؓ了帮助编译器产出更友好的信息Q当Ӟq有许多非常重要的其它原?/span>[12]Q,C++09对“cd的类?#8221;加入first-class的支持,其带来的众多好处会将C++中的泛型~程带向一个新的高度:更友好、更实用、更直观?/span>
 
此外Q?/span>C++的模板元~程没?/span>first-class的语a支持Q一斚w是因为其q用不像一般的模板~程q么q泛Q因而没有这么紧急。另一斚wQ?/span>C++09的时间表也等不及一个成熟的提案。如果以后模板元~程被运用得来广泛的话,?/span>first-class的语a支持是难免的?/span>
 
ȝ
本文?/span>C++模板Q以?/span>C++模板所支持的泛型编E作了一个概览。着重介l了泛型~程诞生的原因,泛型~程的过E和意义Q与其它抽象手段的比较。ƈ?/span>C++中的模板元编E做了一些介l。最后介l了C++模板?/span>C++09中的增强?/span>
 


[1] B. Stroustrup: A History of C++: 1979-1991. Proc ACM History of Programming Languages conference (HOPL-2). March 1993.
[2] http://en.wikipedia.org/wiki/Alexander_Stepanov
[3] http://www.cs.rpi.edu/~musser
[4] 实际上,STL的区间概念被证明是一个不完美的抽象。你有没有发玎ͼ要传递一个区间给一个函敎ͼ如std::sortQ你需要传递两个参敎ͼ一个是区间的开_一个是区间的末。这U分ȝ参数传递方式被证明是不明智的,在一些场合会带来使用上不必要的麻烦。比如你惌P代一l文Ӟ代表q组文g的区间由一个readdir_sequence函数q回Q由于要分离表达一个区_你就必须写:
readdir_sequence entries(".", readdir_sequence::files);
std::for_each(entries.begin(), entries.end(), ::remove);
如果你只想遍历这个区间一ơ的话,你也怸惛_明entriesq个变量Q毕竟多一个名字就多一个篏赘,你也许只惻I
std::for_each(readdir_sequence(".", readdir_sequence::files), ::remove);
下一代C++标准QC++09Q会解决q个问题Q将区间q个抽象定义Z个整体)?/div>
[5] 当然Q语aq没有规定模板实例化的底层实C定要是对每组参数cdl合实例化一个版本出来。但目前的实玎ͼq种Ҏ是最高效的。完全消除了抽象惩罚。另一斚wQOne size fit all的方案也不是不可行,但M有间接调用。这也正说明了静态类型系l的一个典型优点:帮助~译器生成更高效的代码?/div>
[6] http://en.wikipedia.org/wiki/Don't_repeat_yourself
[7] http://en.wikipedia.org/wiki/Duck_typing
[8] 摘自Bjarne Stroustrup的paperQEvolving a language in and for the real world: C++ 1991-2006
[9] 也正因此QD语言加入了语a直接Ҏ板元~程的支持,比如真正工作在编译期的static if-else语句?/div>
[10] http://www.boost-consulting.com/mplbook/
[11] W三章的译见我的blogQ《深度探索元函数》http://blog.csdn.net/pongba/archive/2004/09/01/90642.aspx
[12] ׃幅原因Q这里无法展开详述Concept对C++泛型~程的其它重要意义,有兴的可以参见我的一blogQ《C++0x漫谈pd之:Concept! Concept!》。http://blog.csdn.net/pongba/archive/2007/08/04/1726031.aspx


]]>zz:vc2005l验http://m.tkk7.com/dongwq/archive/2008/12/12/245975.html强摩羯?/dc:creator>强摩羯?/author>Fri, 12 Dec 2008 08:07:00 GMThttp://m.tkk7.com/dongwq/archive/2008/12/12/245975.htmlhttp://m.tkk7.com/dongwq/comments/245975.htmlhttp://m.tkk7.com/dongwq/archive/2008/12/12/245975.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/245975.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/245975.html

VS2005q行提示Q没有找?MSVCR80.dll

d代码Q?br />
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='X86' publicKeyToken='1fc8b3b9a1e18e3b' language='*'\"")

在VS2005中,如果没有上面q行代码Q运行会提示Q没有找?MSVCR80.dll



Visual C++ 如何Q在各种字符串类型之间进行{?/a>


C++实现单g


c++按位操作W?


]]>预编译头文g zzhttp://m.tkk7.com/dongwq/archive/2008/12/12/245966.html强摩羯?/dc:creator>强摩羯?/author>Fri, 12 Dec 2008 07:43:00 GMThttp://m.tkk7.com/dongwq/archive/2008/12/12/245966.htmlhttp://m.tkk7.com/dongwq/comments/245966.htmlhttp://m.tkk7.com/dongwq/archive/2008/12/12/245966.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/245966.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/245966.html

预编译头文g
今天在改一个很大的E序Q慢慢看Q慢慢改。突然发C?c文gQ里面什么也没有Q?

几个头文gQ我一看,我靠Q这不是把简单的问题搞复杂了吗,随手删掉那个c文g?

l果不能~译了,我靠Q?

fatal error C1083: Cannot open precompiled header file: \'Debug/v13_3.pch\':

No such file or directory

怎么rebuild all都不行?

上网查了一下,才搞懂了Q?

Q-Q-Q-Q-Q-Q-Q-Q-ȝQ-Q-Q-

如果工程很大Q头文g很多Q而有几个头文件又是经常要用的Q那?

1。把q些头文件全部写C个头文g里面去,比如写到preh.h

2。写一个preh.cQ里面只一句话Q?include "preh.h"

3。对于preh.cQ在project setting里面讄creat precompiled headersQ对于其?

.c文gQ设|use precompiled header file

//

哈哈

我试了一下,效果很明显,不用precompiled headerQ编译一ơ我可以M个厕所Q用

precompiled headerQ编译的时候,我可以站h怸懒腰Q活动活动就差不多啦

Q-Q-Q-Q-Q{载的文章Q-Q-Q-Q-Q-

预编译头的概念:

所谓的预编译头是把一个工E中的那一部分代码,预先~译好放在一个文仉(通常?

?pch为扩展名?Q这个文件就UCؓ预编译头文gq些预先~译好的代码可以是Q何的

C/C++代码--------甚至是inline的函敎ͼ但是必须是稳定的Q在工程开发的q程中不?

被经常改变。如果这些代码被修改Q则需要重新编译生成预~译头文件。注意生成预~?

译头文g是很耗时间的。同时你得注意预~译头文仉常很大Q通常?-7M大。注意及

时清理那些没有用的预~译头文件?

也许你会问:现在的编译器都有Time stamp的功能,~译器在~译整个工程的时候,?

只会~译那些l过修改的文Ӟ而不会去~译那些从上ơ编译过Q到现在没有被修改过

的文件。那么ؓ什么还要预~译头文件呢Q答案在q里Q我们知道编译器是以文g为单

位编译的Q一个文件经q修改后Q会重新~译整个文gQ当然在q个文g里包含的所?

头文件中的东西(.eg Macro, Preprocesser Q都要重新处理一遍。VC的预~译头文?

保存的正是这部分信息。以避免每次都要重新处理q些头文件?

预编译头的作用:

Ҏ上文介绍Q预~译头文件的作用当然是提高便宜速度了,有了它你没有必要每次

都编译那些不需要经常改变的代码。编译性能当然提高了?

预编译头的用:

要用预~译_我们必须指定一个头文gQ这个头文g包含我们不会l常改变?

代码和其他的头文Ӟ然后我们用这个头文g来生成一个预~译头文Ӟ.pch文gQ?

惛_大家都知?StdAfx.hq个文g。很多h都认是VC提供的一?#8220;pȝU别”?

Q编译器带的一个头文g。其实不是的Q这个文件可以是M名字的。我们来考察一?

典型的由AppWizard生成的MFC Dialog Based E序的预~译头文件。(因ؓAppWizard

会ؓ我们指定好如何用预~译头文Ӟ默认的是StdAfx.hQ这是VCL名字Q。我?

会发现这个头文g里包含了以下的头文gQ?

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4

Common Controls

#include <afxcmn.h>

q些正是使用MFC的必d含的头文Ӟ当然我们不太可能在我们的工程中修改这些头?

件的Q所以说他们是稳定的?

那么我们如何指定它来生成预编译头文g。我们知道一个头文g是不能编译的。所以我

们还需要一个cpp文g来生?pch 文g。这个文仉认的是StdAfx.cpp。在q个文g

里只有一句代码就是:#include “Stdafx.h”。原因是理所当然的,我们仅仅是要它能

够编译而已?D?D?D也就是说Q要的只是它?cpp的扩展名。我们可以用/Yc~译开x?

定StdAfx.cpp来生成一?pch文gQ通过/Fp~译开x指定生成的pch文g的名字。打

开project ->Setting->C/C++ 对话框。把Category指向Precompiled Header。在左边?

树Ş视图里选择整个工程 

Project Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”Q这是?

定生成的.pch文g的名字,默认的通常是 <工程?gt;.pchQ我的示例工E名是PCHQ?

然后Q在左边的树形视N选择StdAfx.cpp.//q时只能选一个cpp文gQ?

q时原来的Project Option变成?Source File OptionQ原来是工程Q现在是一个文?

Q当然变了)。在q里我们可以看到 /Yc开养I/Yc的作用就是指定这个文件来创徏一?

Pch文g?Yc后面的文件名是那个包含了E_代码的头文gQ一个工E里只能有一个文

件的可以有YC开兟뀂VC根据这个选项?StdAfx.cpp~译成一个Obj文g和一个PCH文g

?

然后我们再选择一个其它的文g来看看,//其他cpp文g

在这里,Precomplier 选择?Use ⋯⋯⋯一,头文件是我们指定创徏PCH 文g的stda

fx.h

文g。事实上Q这里是使用工程里的讄Q(如图1Q?Yu”stdafx.h”?

q样Q我们就讄好了预编译头文g。也是_我们可以使用预编译头功能了。以

下是注意事项Q?

1):如果使用?YuQ就是说使用了预~译Q我们在每个.cpp文g的最开_我强调一?

是最开_包含 你指定生pch文g?h文gQ默认是stdafx.hQ不然就会有问题。如

果你没有包含q个文gQ就告诉你Unexpected file end. 如果你不是在最开头包含的Q?

你自p以下q道了Q绝Ҏ很惊人的效果?.

fatal error C1010: unexpected end of file while looking for precompiled

header directive

Generating Code...

2Q如果你把pch文g不小心丢了,~译的时候就会生很多的不正常的行ؓ。根据以?

的分析,你只要让~译器生成一个pch文g。也是说把 stdafx.cppQ即指定/Yc的那?

cpp文gQ从新编译一遍。当然你可以d?Rebuild All。简单一点就是选择那个cpp

文gQ按一下Ctrl + F7可以了。不然可是很费旉的哦?

//

呵呵Q如果你居然耐着性子看到了这里,那么再回到帖子最开始看看我的ȝ吧!

 



]]>zz VC++技术内q(W四版)MW记http://m.tkk7.com/dongwq/archive/2008/08/26/224348.html强摩羯?/dc:creator>强摩羯?/author>Mon, 25 Aug 2008 19:27:00 GMThttp://m.tkk7.com/dongwq/archive/2008/08/26/224348.htmlhttp://m.tkk7.com/dongwq/comments/224348.htmlhttp://m.tkk7.com/dongwq/archive/2008/08/26/224348.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/224348.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/224348.html
『VC++技术内q』(W四版)MW记

关键?/font>QVC++
原作者姓?/font>Qloose_went
文章原出?/font>Qvczx.com

写在前面Q?/strong>

  站长所看的『VC++技术内q』版本ؓ--潘爱民和王国印译清华大学出版的第四版Q因有时工作忙碌Q不能及时更斎ͼ请大家见谅!


W一?Windows的编E模?/a> W二?MFC应用E序框架
W三?消息映射和视囄 W四?资源和编?/a>
W五?基本事g处理 W六?映射模式
W七?滚动视窗 W八?C֤环境c?/a>
W九?GDI对象 W十?windows颜色映射

W一?Windows的编E模?/strong>

  WindowsE序中必要有WinMain函数Q因函数最重要的Q务是创徏该应用程序的ȝ口。WindowsE序与基于MS-DOSE序的最大差别就在于QMS-DOSE序是通过调用操作pȝ的功能来获得用户输入的,而WindowsE序是通过操作pȝ发送的消息来处理用戯入的。Windows消息都是l过严格定义的,q且适用于所有的E序?br />   WINDOWS提供通用的图形设备接口(GUIQ,我们通过调用QGDIQ函数和g打交道,不必理会讑֤环境QWINDOWS会自动将讑֤环境l构映射到相应的物理讑֤?br />   WindowsE序设计中所需要的数据是存储在资源文g中的Q这Pq接器就可以把编译好的二q制代码和二q制资源文gl合h生成可执行程序。资源文件可以包括位图、图标、菜单定义、对话框设计Q甚臛_以包含用戯己定义的格式?br />   WindowsE序允许动态的q接目标模块Qƈ且多个应用程序可以共享同一个动态连接库?br /> VC++的源E序览器能够我们从类或函数的角度来了解或~辑E序Q而不是直接从文g入手。在看别人的源代码时如果能熟l的使用源代码浏览器会事半功倍。源E序览器主要的查看状态有以下几种Q?br /> Definitions and References--选择M函数、变量、类型、宏定义可以看到它在目中的定义Qƈ且在何处和什么地方用到它?br /> Call Graph/Caller Graph--对于所选择的函敎ͼl出它的调用与被调用函数的图C?br /> Derived Class Graph/Base Class Graph--l出cdơ关pȝ囑Ş表示Q可以看到所选择的类的派生类和基cM及成员?br /> File Outline--对于所选的文gQ列出文件中的类、函数和数据成员Q同时还昄它们定义的位|和使用位置?br />   可见Source Brower比vClass View来功能多了很多也更加好用?br />   对于本章学习loose_went大家在VC++6中用AppWizard生成一个空的程序,然后试着看看都有哪些文gQ和他们的类层次、函数、宏、结构的定义Q我是q样q的Q学~程不动手是不行的?


Top of Page

W二?MFC应用E序框架

?MFC是C++的Microsoft Windows API
?MFC产生的应用程序用了标准化的l构?br /> ?MFC产生的应用程序短而运行速度快?br /> ?VCQ+工具降低了编码的复杂性,q当然了Q很多代码都由它代劳了,呵呵?br /> ?MFC库应用程序框架的功能非常丰富?br />   以上说的都是MFC库的优点Q虽然说MFC有着q样多的优点Q但我个Z能盲目的学习它,要想学好Q那么您必须先掌握C++Q这是毋庸置疑的。可能刚开始的时候,您觉得收获很大,也很有趣Q但要进一步提高,没有C++基础是很隄。所以站长徏议大家学习的时候要有先有后Q这h能学好!
应用E序框架是一U类库的集?br />   我们现在先来看一个例子,看看MFC有多么强大!您只需加一行代码,甚至一行都不用加只需要点几下鼠标可以创Z个windows E序Q不信,试一下:
1、打开VC++6从菜单选择NEWQ给目命名?MyApp "?br /> 2、选择MFC AppWizard[exe] 选项Q除STEP 1选择单文档外其他STEP~省?br /> 3、在Class View选择CMyAppViewcȝOnDraw()成员函数双击会在C++~译器看C下内?/font>

void CMyAppView::OnDraw(CDC* pDC)
{
CMyAppDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
?// TODO: add draw code for native data here的位|增加一行代?br /> void CMyAppView::OnDraw(CDC* pDC)
{
CMyAppDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(10,10,"愿vc在线能成为您学习vc最好的朋友Q?); //增加的一?br /> // TODO: add draw code for native data here
}
  完了Q就q么单。编译运行。看C吗?q个E序具备WINDOWSE序的所有特性,例如有菜单、工h、状态栏、最大化、关闭、甚臌有关于对话框、打印预?....全了Q这是AppWizard通过MFC动态创建的一个应用程序。从q个例子可以看出用VC/MFC设计WINDOWSE序多么方便?/font>

下面我们看看书上的例子,以便更进一步了解应用程序框架?br /> 1、先建立一个Win32 Application的应用程序?br /> 2、选择Project->Add to project->Files,分别创徏一个名为MyApp.h和一个名为MyApp.cpp的文件?br /> 3、添加代码:Q最好照敲一下代码到~译器,别用Ctrl+C/Ctrl+VQ?br /> //***********************************************
// MyApp.h
//

class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};

class CMyFrame:public CFrameWnd
{
public:
CMyFrame();
protected:
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};

//*****************************************************
// MyApp.cpp
//

#include "afxwin.h"
#include "myapp.h"
CMyApp theApp;//建立一个CMyAPP对象
BOOL CMyApp::InitInstance ()
{
m_pMainWnd=new CMyFrame();
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
return TRUE;
}

BEGIN_MESSAGE_MAP(CMyFrame,CFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()

CMyFrame::CMyFrame(){
Create(NULL,"MYAPP Application");
}
void CMyFrame::OnLButtonDown (UINT nFlags,CPoint point)
{
TRACE("Entering CMyFrame::OnLButtonDown - %lx,%d,%d\n",
(long)nFlags,point.x ,point.y);
}

void CMyFrame::OnPaint ()
{
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
}

4、编译运行,报错。ؓ什么呢Q原来还没有dMFC的支持,在Project Setting选项General属性页选择"Use MFC in a Static Library"
5、再按Ctrl+F5Q怎么P单吧Q?br /> 让我们看看这个程序中的一些元素?br /> ①WinMain函数QWindowsL要求每个应用E序都要有WinMain函数的,您之所以看不见Q是因ؓ它已l隐藏在应用E序框架内部了?br /> ②CMyAppc:CMyAppcȝ对象代表一个应用程序,CWinApp基类军_它的大部分行为?br /> ③应用程序的启动Q当开始运行应用程序时WINDOWS会调用WinMain函数QWinMain会查找该应用E序的全局对象theApp?br /> ④CMyApp::InitInstance成员函数Q发现theApp后自动调用重载的虚函数InitInstance来完成主H口的构造和昄工作?br /> ⑤CWinApp::Run成员函数QWinMain在调用InitInstance之后紧接着调用Run函数Q它被隐藏在基类中负责传递应用程序的消息l相映的H口?br /> ⑥CMyFramec:此类的对象代表着应用E序的主H口。它的构造函数调用基cCFrameWnd的Create函数创徏具体的窗口结构?br /> ⑦CMyFrame::OnLButtonDown函数Q演C消息处理机Ӟ当鼠标坐键被按下q一事g被映到CMyFrame的OnLButtonDown函数上,如果你选择F5q行~译q行的话可以在调试窗口看到TRACE宏显C的cM下面的信?br /> Entering CMyFrame::OnLButtonDown - 1,309,119
Entering CMyFrame::OnLButtonDown - 1,408,221
⑧CMyFrame::OnPaint函数Q应用程序每ơ重新绘制窗口都需要调用此函数Q将昄"Hello World!"攑֜q里是因为每ơ窗口发生变化时保证"Hello World!"被显C,你可以试着语句:
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
写在别出Q例如写?br /> void CMyFrame::OnLButtonDown (UINT nFlags,CPoint point)
{
TRACE("Entering CMyFrame::OnLButtonDown - %lx,%d,%d\n",
(long)nFlags,point.x ,point.y);
CPaintDC dc(this);
dc.TextOut (0,0,"Hello World!");
}
q行后当点击左键时显C?Hello World!"Q但当窗口最化再最大化?Hello World!"不见了?br /> ⑧关闭应用程序:用户关闭应用E序时会有一pd事g发生。首先CMyFrame对象被删除,然后退出RunQ进而退出WinMainQ最后删除CMyApp对象?br />   通过上面的示例我们看见程序的大部分功能包含在基类CWinApp和CFrameWnd中,我们只写了很的函数Q便可以完成很复杂的功能。所以应用程序框架不仅仅是一U类库,它还定义了应用程序的l构Q除了基cdq包括WinMain函数Q以及用来支持消息处理、诊断、DLL、等都包含在应用E序框架中?


Top of Page

W三?消息映射和视囄

  MFC库应用程序框架没有采用虚函数来处理windows消息Q而是通过宏将消息映射到派生类相应的成员函C。文档-视图l构是应用程序框架的核心Q它把数据从用户Ҏ据的观察中分d来,q样做最大的好处是同一个数据可以对应多个视图。比如同一个股报h据,既可以有报表观察H口Q也可以有图形观察窗口,明白了否Q?br />   视图单来说就是一个普通的H口Q对于程序员来说是一个从MFC库中CviewcL生出来的cȝ一个对象。视囄分ؓ两个源文件模块:头文ӞHQ和源代码文ӞCPPQ?br /> 用Appwizard创徏一个SDI应用E序Q生了如下文gQ假讑ַE名为Exc01Q:
Exc01.dsp 目文gQVisual Studio用它来创建应用程?br /> Exc01.dsw 工作I间文gQ包含一个项目Exc01.dsp
Exc01.rc ASCII码资源描q文?br /> Exc01View.cpp 包含CExc01ViewcL员函数和视图cL?br /> Exc01View.h 包含CExc01Viewcd义的视图cd文g
Exc01.opt 二进制文Ӟ告诉Developer Studio本项目的哪些文g是打开的,又是如何排序?br /> Readme.txt 用来解释所产生的所有文件的文本文g
Resource.h 包含#define帔R定义的头文g
  从Exc01View.cpp和Exc01View.h的代码中可以看出Q这两个文g已经完全定义了CExc01Viewc,而该cL是此应用E序的核心。CExc01Viewcȝ对象与应用程序的视窗相关联,应用E序的所?动作"都会在这个视H中昄出来?br />   CExc01Viewcȝ两个最重要的基cLCWnd和CViewcRCWndcL供了CExc01View的窗口属性,而CViewcd提供了它和应用程序框架的其它部分之间的联p,特别是和文档以及框架H口之间的联pR这一点一定要C?br />   下面我们来看一下如何在视窗内绘图。最重要的一个函数是OnDraw()函数Q它是一个虚函数Q每ơ窗口被重画Ӟ应用E序都要先调用这个函数。注意:管可以随时对窗口绘Ӟ但最好还是等变化内容U篏C定程度后再教lOnDraw()函数处理Q这h率会高一些?br /> 在MFC中,讑֤环境是由C++的CDCcd象来表示的,该对象被作ؓ参数传给Ondraw()函数Q这P我们可以调用CDC的许多成员函数来完成各种l制了?br /> 扑ֈOnDraw()函数Q用以下语句替换函数原来的内容:
pDC->TextOut( 0, 0, "Hello World!" );
pDC->Ellipse(CRect(0,20,100,120));
再编译运行,看到了什么?
  TextOut和Ellipse都是讑֤环境cCDC的成员函敎ͼMFC库提供了一个用来表Cwindows矩Ş的类CRectQ在q里CRect的一个时对象被作ؓ参数传递给 了Ellipse函数Q当外接矩Ş的宽和高相等ӞEllipse函数qZ圆?


Top of Page

W四?资源和编?/strong>

  资源文gQ就是以应用E序名和扩展名是.rc的文Ӟ很大E度上决定了应用E序的用L面。在VC++中资源文件包括以下内容:
Accelerator //模拟菜单和工h选择的键盘定?
Dialog //对话框的布局及内?
Icon //图标有两U一U是16X16一U是32X32?
Menu //应用E序的主菜单及所属的弹出式菜?
String table //一些字W串Q不属于C++源代码部?
Toolbar //工具条?
Version //E序的描q、版本号、支持语a信息?
  除了以上信息Q?rc文gq包含了以下语句Q?#include "afxres.h" #include "afxres.rc" 它们的作用是把适合于所有应用程序的一些通用MFC库资源包含进来,其中包括字符丌Ӏ图形按钮以及打印所需的一些元素?
  关于资源~辑器的使用׃多说了,因ؓ它的操作很简单,需要注意的是虽然resource.h是一个ASCII码文件可以用文本~辑器进行编辑,但如果用文本编辑器q行~辑的话Q下ơ再使用资源~辑器时所做的修改有可能丢失,所以我们应该在量在资源编辑器中编辑应用程序的资源Q新增的资源内容回自动的d在我们的E序相应位置Q例如resource.h而不用我们操心?
  ~译在VC++中有两种模式Q一U是Release Build另一U是Debug Build。它们之间的区别在于QRelease Build不对源代码进行调试,不考虑MFC的诊断宏Q用的是MFC Release库,~译十对应用E序的速度q行优化Q而Debug Build则正好相反,它允许对源代码进行调试,可以定义和用MFC的诊断宏Q采用MFC Debug库,寚w度没有优化。所以我们应该在Debug模式下开发应用程序,然后在Release模式下发布应用程序。在我们的工E文件夹下会有一个Debug文g夹和一个Release文g夹分别存放输出文件和中间文g?
  诊断宏是我们~译E序时检程序状态的有利工具Q例如上两篇用到的TRACE宏,可以在DebugH口获得你需要的诊断信息Q而不用设|对话框之类的方法,在发布时Release会自动o掉此信息?
  Z更好的管理项目,最好理解系l是如何处理预编译头文g的。VCQ+有两个预~译pȝQ自动的和手工的。这一部分W者就不多说了Q徏议读者好好看看?


Top of Page

W五?基本事g处理

  用户在视H中的Q何一个操作,都会引vWindows自动发送一个消息给该视H。我们以一个例子来说明Q比如我们在视窗中按下鼠标左键,Windows׃发送ON_LBUTTONDOWN消息l视H,那么在视H类中就必须包含下面的成员函敎ͼ
Void CmyView::OnLButtonDown(UINT nFlags, Cpoint point)
{
//event processing code here
}
  在类头文件中也要包含相应的函数声明:
afx_msg void OnLButtonDown(UINT nFlags, Cpoint point)
在代码文件中q要有一个消息映宏Q用于将OnLButtonDown函数和应用程序框架联pd一P
BEGIN_MESSAGE_MAP(CmyView, CView)
ON_WM_LBUTTONDOWN()
// other message map entries
END_MESSAGE_MAP
  最后,在类库头文g中包含如下语句:
DECLARE_MESSAGE_MAP()
  以上q些步骤Q我们都可以借助于ClassWizard来完成。这是消息映射的过E?

  MFC库对140Uwindows消息直接提供了消息控制函敎ͼq且我们q可以自己定义自q消息Q下面列出的五种消息是我们应该特别注意的QMSDN上有更详l的内容Q?br /> WM_CREATE
  该消息是Windows发给视图的第一个消息。当应用E序框架调用create函数时该消息便会被发送,此时H口q未创徏完成Q不可见Q因此在消息控制函数OnCreate内不能调用那些依赖窗口处于完全激zȝ态的Windows函数。如果需要可以在重蝲的OnInitialUpdate函数内调用。不q注意在SDI应用E序OnInitialUpdate函数可能被多ơ调用?br /> WM_CLOSE
  当用户关闭窗口时Q系l会发送WM_CLOSE消息。如果派生类重新定义了OnClose函数Q就可以完全控制关闭q程Q可以将提醒用户存盘之类的工作放在这里完成。我们可以通过重蝲CDocument::SaveModified虚函数达到相同的目的?br /> WM_QUERYENDSESSION
  从字面的意思看可以看出,当用户退出WindowsӞ或者调用了ExitWindows 函数时。Windows会发送WM_QUERYENDSESSION消息l所有的正在q行的应用程序,由OnQueryEndSession消息映射函数Ҏ息进行处理。在它之后应该是WM_ENDSESSION 消息?br /> WM_DESTROY
  在Windows发送WM_CLOSE消息后,紧接着会发送WM_DESTROY消息Q虽然窗口已lClose但实际上q没有完全清除,在Q务管理器中还可以看见应用E序的进E(我想很多木马或病毒都是无H口的程序,它们的做法是生成了已l活动状态的H口但不昄出来Q,利用q个消息控制函数便可以对依赖于当前窗口存在的东西做清除工作,不过一定要注意Q应该调用基cȝOnDestroy函数Q而不能在用户自己的视囄OnDestroy函数中终止窗口的析构q程Q终止析构过E应该在OnClose函数中?br /> WM_NCDESTROY
  当窗口被取消所发送的最后一个消息就是这个消息。我们可以在OnNcDestroy函数中做一些不依赖该窗口是否处于活动状态的最后的处理工作Q(我实在想不出q需要做什么?那位朋友能给个例子)Q注意一定要调用基类中的OnNcDestroy函数?/p>

  MFC库中非静态数据成员的名字以m_为前~?br />   一个窗口具有一个矩形的"客户区域"QCWnd中的GetClient成员函数可以l出客户区域的大,只允许在客户区域内绘图?br />   标准的windows应用E序会首先登C个窗口类Q这不同于C++c,同时在处理过E中Q还需要对每个cL定窗口过E。每ơ应用程序调用CreateWindow建立一个窗口时Q都要指定一个窗口类作ؓ参数Q这样就把新建立的窗口和H口q程函数q接h了,每次windowsl窗口发送消息的时候,q个函数׃被调用,以检查用参数传进来的消息码?br />

Top of Page

W六?映射模式

  所谓映模式,说白了就是坐标系。在默认情况下,Windows所l图像单位ؓ像素Q这是因备环境用了默认的映射模式MM_TEXTQ所以如下语句所l图形ؓ长和宽都?00像素的方块:   pDC->Rectangle(CRect(0,0,200,200));
  那么我们要绘制一个长和宽都是4厘米的方块该怎么做呢Q这必L变设备环境的默认映射模式为MM_HIMETRICQ它的图像单位ؓ1/100mmQ而不是像素了。它的y轴方向和MM_TEXT的相反,它的向下为递减的,因此用如下语句就可以l出4×4cm的方块了Q?
pDC->SetMapMode( MM_HIMETRIC);
pDC->Rectangle(CRect(0,0,4000,-4000));
  下面我们再来了解一下Windows都提供了哪些映射模式?br /> 1、MM_TEXT映射模式
  q种模式下,l图单位为像素,x轴向右递增Qy轴向下递增Q我们可以用CDC的SetViewPortOrg和SetWindowOrg函数来改变坐标原点的位置Q下面的代码是把坐标原点设在了Q?00,100Q处Q画了一?00×200像素的方块,此时逻辑坐标点(100,100Q被映射C讑֤坐标点(0,0Q处Q下一的滚动H口使用的就是这U变换?
Void CmyView::OnDraw( CDC *pDC ){
pDC->SetMapMode(MM_TEXT);
pDC->SetWindowOrg(Cpoint(100,100));
pDC->Rectangle(CRect(100,100,200,200));
}
2、固定比例映模?
  Windows提供了一l非帔R要的固定比例p模式Q所有这U模式都遵@x轴向右递减Qy轴向下递减的规则,而且我们无法其改变。固定比例模式之间唯一的差别就在于实际的比例因子。下表列Zp模式和比例因子的对应情况Q?

映射模式 逻辑单位
MM_LOENGLISH 0.01英寸
MM_HIENGLISH 0.001英寸
MM_LOMETRIC 0.1mm
MM_HIMETRIC 0.01mm
MM_TWIPS 1/1440英寸

  MM_TWIPS模式常用于打印机?
3、可变比例映模?
  Windowsq提供了两种映射模式MM_ISOTROPIC和MM_ANISOTROPICQ这两种模式允许我们修改比例因子和坐标原炏V在MM_ISOTROPIC模式下,U|比L1:1Q就像改变图像时锁定比例一P而MM_ANISOTROPIC模式则可以独立的改变x和y的比例因子,卛_可以变成扁圆?
  以上是常见的映模式,W者徏议:我们没必要死Cq些模式Q只是到用的时候会用就可以了,哪怕查查MSDNQ这个东东真好!
  在设|了映射模式和相应参C后,我们可以用CDC的LPtoDP函数逻辑坐标转换备坐标,用DptoLP函数设备坐标{换ؓ逻辑坐标。那么我们什么时候用什么样的坐标呢Q有一些规则如下:
?可以认ؓCDC的所有成员函数都以逻辑坐标为参?
?可以认ؓCWnd的所有成员函数都以设备坐标ؓ参数
?所有选中试都应该选用讑֤坐标Q区域的定义应采用设备坐标,某些像CRect::PtInRect之类的函数只有采用设备坐标才能有正确的结?
?一些长期用的值用逻辑坐标来保存,如果用设备坐标,那么只要用户对窗口进行一下滚动,坐标׃再有效了
  一般情况下Q我们在CView的虚函数OnPrepareDC中设|映模式,应用E序框架在调用OnDraw函数之前调用q个虚函数?


Top of Page

W七?滚动视窗

  CViewcdƈ不直接支持窗口滚动,如要实现H口滚动Q就要用到CView的派生类CScrollViewc,CScrollView的成员函数能够处理滚动条q发送给视图WM_HSCROLL和WM_VSCROLL消息Q从而实现窗口的滚动?br />   在文档-视图l构中,视图H口建立以后Q框架最先调用OnInitialUpdate虚函敎ͼ在框架第一ơ调用OnDraw函数前也是先调用OnInitialUpdate函数Q因此在OnInitialUpdate函数中设|滚动视H的初始化最合适?br />   下面我们来创徏一个滚动示例程序aQ?br />   1?用AppWizard创徏一个文档-视图E序aQ注意在W六步时讄CAView的基cd为CScrollView而不是CView?br />   2?在CAView中加入数据成员m_rectEllipse和m_nColor?br />   3?修改OnInitialUpdate函数如下Q?br /> void CAView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();

CSize sizeTotal( 20000, 30000 ); //逻辑H口大小20×30cm
CSize sizePage( sizeTotal.cx/2, sizeTotal.cy/2 );
CSize sizeLine( sizeTotal.cx/50, sizeTotal.cy/50 );
SetScrollSizes( MM_HIMETRIC, sizeTotal, sizePage, sizeLine );

}
4?用ClassWizard产生Ҏ息WM_KEYDOW控制的OnKeyDown函数Qƈ~辑代码如下Q?br /> void CAView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default

switch( cChar ){
case VK_HOME:
OnVScroll( SB_TOP, 0, NULL );
OnHScroll( SB_LEFT, 0, NULL );
break;
case VK_END:
OnVScroll( SB_BOTTOM, 0, NULL );
OnHScroll( SB_RIGHT, 0, NULL );
break;
case VK_UP:
OnVScroll( SB_LINEUP, 0, NULL );
break;
case VK_DOWN:
OnVScroll( SB_LINEDOWN, 0, NULL );
break;
case VK_PRIOR:
OnVScroll( SB_PAGEUP, 0, NULL );
break;
case VK_NEXT:
OnVScroll( SB_PAGEDOWN, 0, NULL );
break;
case VK_LEFT:
OnHScroll( SB_LINELEFT, 0, NULL );
break;
case VK_RIGHT( SB_LINERIGHT, 0, NULL );
break;
default:
break;
}
?br /> 5?~辑构造函数和OnDraw函数如下Q?br /> CAView::CAView():m_rectEllipse( 0, 0, 4000, -4000 )
{
// TODO: add construction code here
m_nColor = GRAY_BRUSH;
}

void CAView::OnDraw(CDC* pDC)
{
pDC->SelectStockObject( m_nColor );
pDC->Ellipse( m_rectEllipse );
}
6?映射WM_LBUTTONDOWN消息q编辑消息处理函数OnLButtonDown如下Q?br /> void CAView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CClientDC dc( this );
OnPrepareDC( &dc );
CRect rectDevice = m_rectEllipse;
dc.LPtoDP( rectDevice );
if( rectDevice.PtInRect( point ) ){
if( m_nColor = GRAY_BRUSH )
m_nColor = WHITE_BRUSH;
else
m_nColor = GRAY_BRUSH;
}
InvalidateRect( rectDevice );
}
~译q运行看看结果吧?br /> 另外Q我们要特别注意下面五种比较Ҏ的windows消息Q?br /> 1?WM_CREATE消息
该消息是windows发给视图的第一个消息,׃应用E序框架调用Create函数时该消息׃被发送,而此时窗口创未完成,因此在Create函数内不能调用那些依赖于H口处于完全Ȁzȝ态的windows函数。不q对于SDI应用E序Q在视图生存期间QOnInitialUpdate函数可以被调用多ơ?br /> 2?WM_CLOSE消息
当用户从pȝ菜单中关闭窗口或者父H口被关闭时Qwindows会发送WM_CLOSE消息?br /> 3?WM_QUERYENDSESSION消息
当用户退出windowsӞwindows׃发送WM_QUERYENDSESSION消息l正在运行的E序Q处理这个消息的映射函数为OnQueryEndSession?br /> 4?WM_DESTROY消息
Windows在发送完WM_CLOSE消息后,紧接着发送WM_DESTROY消息Q消息映函CؓOnDestroy。当E序接收到该消息Ӟ它将假定此时视窗已经消失Q但仍处于活动状态。利用这个消息控制函敎ͼ可以对依赖于当前窗口的所有东西作清除工作Q不q一定要CQ应该用基类的OnDestroy而不能在自己视图中的OnDestroy?l止"H口的析构过E,l止析构的处理应该在OnClose函数中?br /> 5?WM_NCDESTROY消息
当窗口被取消时发送的最后一个消息就是这个消息,׃此时所有的H口都被关闭Q所以我们可以在OnNcDestroy函数中做一些不依赖于窗口是否处于激zȝ态的最后处理工作,不过一定要调用基类的OnNcDestroy函数。不要在OnNcDestroy中取消动态申LH口对象Q这一工作是由CWnd的一个特D虚函数PostNcDestroy来完成的Q它是由基类的OnNcDestroy来调用的。何时取消窗口对象最为合适呢Q去看MFC的联机文档吧Q?br />

Top of Page

W八?讑֤环境c?/strong>

  ME序在画图时都需要调用图形设备接口( GDI Q函敎ͼ GDI 包含了一些绘制点、线、矩形、椭圆、位图以及文本的函数?Windows 的设备环境是 GDI 的关键元素,它代表了物理讑֤Q每一?C++ 讑֤环境对象都有与之对应?Windows 讑֤环境Qƈ通过一?32 位的 HDC 句柄来标识?

  MFC 中的基类 CDC 包含了绘图所需要的所有成员函敎ͼq且除了 CMetaFileDC cdQ所有的zc都只有构造函数和析构函数不同。对于显C器来说Q常用的zcL CClientDC ?CWindowDC ?

  昄讑֤环境的类 CClientDC ?CWindowDC Q?CClientDC cȝ囑֏局限于客户区域内,即不包含Ҏ、菜单栏和标题栏Q?CWindowDC cd以。简单来_如果创徏 CclientDC 对象Q点Q?0,0 Q指客户区域的左上角Q如果创建的?CWindowDC 对象Q则点( 0,0 Q指整个屏幕的左上角?

  在创?CDC 对象的时候,不要忘记在合适的时候将它删除,不然E序在退Z前有部分内存就会丢失。要保证讑֤环境对象能够被适时的删除,可以有两U方法:

一U是在堆栈中构造对象,比如?OnLButtonDown 函数中,它的析构函数在函数返回时自动被调用?

void CMyView::OnLButtonDown(UINT nFlags,CPoint point){

CRect rect;

CClientDC dc(this); //constructs dc on the stack

} //dc automatically destroyed

另一U是通过调用 CWnd 的成员函?GetDC 来获得设备环境指针,但此时必要调用 RleaseDC 来释放设备环境?

void CMyView::OnLButtonDown(UINT nFlags,CPoint point){

CRect rect;

CDC *pDC=GetDC();

pDC->GetClipBox(rect);

ReleaseDC(pDC); // 不要忘了q句

}

注意Q千万不要删除作为参C指针形式传递给 OnDraw 函数?CDC 对象Q应用程序框架会自动控制它的删除?

在绘图时我们M开讑֤环境Q那么在l图时我们就要依赖于讑֤环境的当前状态,q种状态包括:

•  被选中?GDI l图对象Q如W、刷子和字体{?

•  l图时的~放寸的映模?

•  其他各种l节Q如文本的对齐方式,多边形的填充状?

  创徏讑֤环境对象Ӟ通常会有些默认的Ҏ,而其他特性都是通过 CDC cȝ成员函数来设定的Q可以通过重蝲 SelectObject 函数来将 GDI 对象选进讑֤环境中?

  如果我们要重新编?OnPaint 函数Q就需要?CPaintDC c,q个cL比较Ҏ的,它的构造函数和析构函数所完成的工作都是针ҎC用的,当我们一旦获得一?CDC 指针Q就可以把它当成M讑֤环境指针来用?/font>

Top of Page

W九?GDI对象

  所?GDI 对象c都是由抽象基类 CGdiObject z出来的。下面是 GDI zcd表:

  CBitmap Q?位图是一U位矩阵Q每一个显C像素都对应一个或多个位,我们可以用位图来表示囑փQ也可以用它来创建刷子?

CBrush Q?刷子定义了一U位囑Ş式的像素Q用它可以对区域内部填充颜色?

CFont Q?字体是一U具有某U风格和寸的所有字W的集合?

CPalette Q?调色板是一U颜色映接口?

CPen Q?W是一U画U和有ŞҎ的工P可以指定ȝ的宽度,以及画虚U,实线{?

CRgn Q?区域是一U范_可以用它来填充、裁剪以及鼠标点中测试?

  我们只需要构?CGdiObject cȝzcd象,而无需构造它的对象,有些 GDI zcd许构造函C步完成创建对象的dQ如 CPen ?CBrush 。而有些派生类的对象要两步Q如 CFont ?CRgn Q首先要调用默认的构造函敎ͼ然后q要调用相应的创建函敎ͼ?CreateFont ?CreatePolygonRgn {?

  CGdiObject cL一个虚析构函数Q如果构造了一个它的派生类的对象,则在E序退Z前要其删除Qؓ了删除它Q要先将其从讑֤环境中分d来。那么如何分dQ其实, CDC cȝ SelectObject 成员函数在将 GDI 对象选进讑֤环境的同Ӟ它已l从讑֤环境中分d来了Q但在未选中新的对象前,q不能将旧的对象分离。所以在选进自己?GDI 对象Ӟ原来的 GDI 对象也保存v来,d完成后,再将其恢复,q样可以将自己?GDI 对象分离q删除了。下面看一个例子:

void CMyView::OnDraw( CDC *pDC ){

CPen newPen( PS_DASHDOTDOT, 2, (COLORREF)0); //black 2 pixels wide

CPen * pOldPen = pDC->SelectObject( &newPen );

pDC->MoveTo( 10, 10 );

pDC->LineTo( 110, 10 );

pDC->SelectObject( pOldPen ); //newPen 被分?

} //newPen 在函数退出时自动删除

  对于一些库存的 GDI 对象Q由于它们是 windows pȝ的一部分Q因此我没有必要删除它们?MFC 库函?SelectStockObject 可以一个库存对象选进讑֤环境中,q返回原先被选中对象的指针,同时使该对象被分R在上例中,我们可以用库存对象代替“?#8221;对象Q?

void CMyView::OnDraw( CDC *pDC ){

CPen newPen( PS_DASHDOTDOT, 2, (COLORREF)0); //black 2 pixels wide

pDC->MoveTo( 10, 10 );

pDC->LineTo( 110, 10 );

pDC->SelectStockObject( BLACK_PEN ); //newPen 被分?

} //newPen 在函数退出时自动删除

  对于昄讑֤环境来说Q在每个消息控制函数的入口处Q设备环境都是未被初始化的,因此每次都必M头开始设|设备环境,׃ SelectObject q回?GDI 对象指针的时性,而应用程序框架在函数q回时会删除 C++ 临时对象指针Q所以不能简单地设备环境指针保存在cȝ数据成员中,而要借助?GetSafeHandle 成员函数来将它{换ؓ windows 句柄Q唯一能够持久存在?GDI 标识Q?

  注意Q当删除?SelectObject q回的指针所指向的对象时Q一定要当心Q如果该对象是我们自qLQ可以删除,如果是时的Q则不能随便删除?

]]>
zz:vc常用技巧ȝ http://m.tkk7.com/dongwq/archive/2008/08/26/224347.html强摩羯?/dc:creator>强摩羯?/author>Mon, 25 Aug 2008 18:59:00 GMThttp://m.tkk7.com/dongwq/archive/2008/08/26/224347.htmlhttp://m.tkk7.com/dongwq/comments/224347.htmlhttp://m.tkk7.com/dongwq/archive/2008/08/26/224347.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/224347.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/224347.html阅读全文

]]>
zz:~程修养 http://m.tkk7.com/dongwq/archive/2007/10/05/150460.html强摩羯?/dc:creator>强摩羯?/author>Thu, 04 Oct 2007 16:50:00 GMThttp://m.tkk7.com/dongwq/archive/2007/10/05/150460.htmlhttp://m.tkk7.com/dongwq/comments/150460.htmlhttp://m.tkk7.com/dongwq/archive/2007/10/05/150460.html#Feedback1http://m.tkk7.com/dongwq/comments/commentRss/150460.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/150460.html我认为好的程序员应该有以下几斚w的素质:
 1、有专研_Q勤学善问、D一反三?
 2、积极向上的态度Q有创造性思维?
 3、与人积极交沟通的能力Q有团队_?
 4、谦虚}慎,戒骄戒燥?
5、写出的代码质量高。包括:代码的稳定、易诅R规范、易l护、专业?
q些都是E序员的修养Q这里我惌谈“编E修兠Z,也就是上qC的第5?nbsp; 阅读全文

]]>
zz:计算机科学与技术学习反思录http://m.tkk7.com/dongwq/archive/2007/10/04/150454.html强摩羯?/dc:creator>强摩羯?/author>Thu, 04 Oct 2007 15:53:00 GMThttp://m.tkk7.com/dongwq/archive/2007/10/04/150454.htmlhttp://m.tkk7.com/dongwq/comments/150454.htmlhttp://m.tkk7.com/dongwq/archive/2007/10/04/150454.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/150454.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/150454.html
很老的帖子了,也不知道是谁写的

计算机科学与技术这一门科学深q吸引着我们q些同学们,上计机pdl有q三q?
了,自己也做了一些思?我一直认机U学与技术这门专业,在本U阶D|不可?
切分成计机U学和计机技术的Q因机U学需要相当多的实践,而实践需要技
术;每一个h(包括非计机专业)Q掌握简单的计算机技术都很容易(包括E序?
计)Q但计算Z业的优势在于,我们掌握许多其他专业q不“深I”的东西Q例
如,法Q体pȝ构,{等。非计算Z业的人可以很Ҏ地做一个芯片,写一D늨
序,但他们做不出计算Z业能够做出来的大型系l。(与司徒R南兄的谈话)今天?
想专门谈一谈计机U学Qƈ重Ҏ在计理Z?

  阅读全文

]]>
计算机科学与技术学习心?zz)http://m.tkk7.com/dongwq/archive/2007/10/04/150434.html强摩羯?/dc:creator>强摩羯?/author>Thu, 04 Oct 2007 13:52:00 GMThttp://m.tkk7.com/dongwq/archive/2007/10/04/150434.htmlhttp://m.tkk7.com/dongwq/comments/150434.htmlhttp://m.tkk7.com/dongwq/archive/2007/10/04/150434.html#Feedback0http://m.tkk7.com/dongwq/comments/commentRss/150434.htmlhttp://m.tkk7.com/dongwq/services/trackbacks/150434.html
计算机科学与技术学习心?

撰文 曾毅
  阅读全文

]]>
zz:批处理高U精华ȝ?/title><link>http://m.tkk7.com/dongwq/archive/2007/08/13/136259.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Sun, 12 Aug 2007 16:46:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2007/08/13/136259.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/136259.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2007/08/13/136259.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/136259.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/136259.html</trackback:ping><description><![CDATA[     摘要: q是一技术教E,我会用很单的文字表达清楚自己的意思,你要?识字p看懂Q就能学到知识。写q篇教程的目的,是让每一个看q这些文字的朋友C一句话Q如果爱可以让事情变的更单,那么p它简单吧Q看q篇教程?ҎQ就是慢Q慢慢的Q如同品一个女人、一杯茗Ӟ你会发现很多以前在眼前的东西突然变的很遥远Q而有些很遥远的东西却又突然回C眼前?<br> <br>?概述一下批处理是个什么东东。批处理的定义,至今我也没能l出一个合适的----众多高手们也都没l出----反正我不知道----看了我也不一定信? ---我是个菜鸟,当然更不用说了Q但我想ȝZ个“比较合适的”,而且我也怿自己可以把它解释的很清楚Q让更多的菜鸟都知道q是个什么东东,你用 q个东东可以q什么事情。或怽会因文章而“无条g׃批处理”,那么我的目的pC----我就是要让你׃它,我就q么拽,你能怎么着Q??的,爱有时候就q么拽,是q么没理由,是q么不要脸!真的Q?<br>  <a href='http://m.tkk7.com/dongwq/archive/2007/08/13/136259.html'>阅读全文</a><img src ="http://m.tkk7.com/dongwq/aggbug/136259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2007-08-13 00:46 <a href="http://m.tkk7.com/dongwq/archive/2007/08/13/136259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz:vc++常见的问题解{?/title><link>http://m.tkk7.com/dongwq/archive/2007/08/07/135099.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Tue, 07 Aug 2007 15:16:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2007/08/07/135099.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/135099.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2007/08/07/135099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/135099.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/135099.html</trackback:ping><description><![CDATA[<div id="c4ikuu4" class=tit>vc++常见的问题解{?/div> <div id="yak2oi6" class=date>2007-07-27 11:00</div> <table style="TABLE-LAYOUT: fixed"> <tbody> <tr> <td> <div id="makskgg" class=cnt>1Qfatal error C1010: unexpected end of file while looking for precompiled header directive该如何解?<br>如果发生错误的文件是由其他的C代码文gdq入当前工程而引LQ则Alt+F7q入当前工程的SettingsQ选择C/C++选项卡,从Categoryl合框中选中Precompiled HeadersQ选择Not Using Precompiled headers。确?<br>如果发生错误的文件原本是该工E中的,则检查该文g头部有没?include "stdafx.h"语句Q没有的话添加?<br>如果q不行,也有可能是定义的cLl构体等最后忘了加分号Q注意一下?<br>2Qfatal error RC1015: cannot open include file ’afxres.h’.该如何解?<br>#include "afxres.h"语句是在.rc文g中的Q而afxres.h文g在VC的安装目录中?\VC98\MFC\INCLUDE目录中,所以着重查一下Tools菜单中Options对话框中的Directories中的包括文g的\径是否正,是否在VC的安装\径中Q不是的话,改过来,如果q方面没问题Q则到其他机器中拯afxres.h到相应的目录?<br>3QDll分配的内存块,应用E序释放Q结果报异常?<br>用GlobalAlloc()代替new, 用GlobalFree() 代替delete׃会出错了 <br>其实q有一个办法,是把dll的Settings的C/C++选项卡的Code Generation的Use Run-time liberaryҎDebug Multithreaded DLLQ在Release版本中改成Multithreaded DLLQ就可以直接使用new和delete了,没问?<br>比较规范点的做法一般是DLL分配的内存由DLL释放。在DLL中加一个函数释攑ֆ存不是更好吗?<br>4Q发现打印预览的囑Ş明显比屏q显C图形小Q怎么办? <br>q多半是CDC映射模式的选择引v的,~省状态下Q选择的是MM_TEXT模式QMM_TEXT以设备的像素点ؓ单位Q而不同设备的像素点的大小不同Q打印机的分辨率比显C器要高很多Q所以导致同样图形在打印时候变。解决之道是l一使用其他定长的映模式,比如MM_HIMETRIC{等QCDC::SetMapMode()改变映射模式Q?<br>5QCString、char*、string、int、_bstr_t、CTime、COleDateTime{等的相互{换,如何判断一个字W串是一个QҎQ?<br><br>#include<string> <br>using namespace std; <br>#include <COMDEF.H> <br><br>{ <br>CString strCString="ABC"; <br>char strchar[256],*pstr; <br><br>pstr=(LPSTR)(LPCTSTR)strCString; //CString---->char* <br>strcpy(strchar,(LPSTR)(LPCTSTR)strCString); //CString---->char[] <br><br>_bstr_t strbstr=pstr; //char*---->_bstr_t <br>WCHAR *strWCHAR=strbstr; //b_str_t--->UNICODE <br><br>strbstr=strWCHAR; <br>pstr=strbstr; //UNICODE---->char* <br><br>strCString="10"; <br>int istr=atoi((LPSTR)(LPCTSTR)strCString); //CString、char[]、char*------>int <br>strCString.Format("%d",istr); //int----->CString <br>sprintf(strchar,"%d",istr); //int----->char[] <br><br>pstr=new char[256]; //字符串申L?<br>strcpy(pstr,"ABC"); //字符串赋?<br>delete []pstr; //字符串释?<br><br>string strstring="ABC"; <br>pstr=(char*)strstring.c_str(); //string---->char* <br><br>strCString="2003-10-27 6:24:37"; //CString--->COleDateTime <br>COleVariant vtime(strCString); <br>vtime.ChangeType(VT_DATE); <br>COleDateTime time4=vtime; <br><br><br><br>COleDateTime time1(1977,4,16,2,2,2); //COleDataTime--->CTime <br>SYSTEMTIME systime; <br>VariantTimeToSystemTime(time1, &systime); <br>CTime tm(systime); <br><br>time_t time2=tm.GetTime(); //CTime--->time_t <br>COleDateTime time3(time2); //time_t--->COleDateTime <br><br>//判断字符串是否是某种cd <br>CString sValue("123.1"); <br>COleVariant vValue(sValue); <br><br>BOOL bStrIsFloat = (SUCCEEDED(VariantChangeType(&vValue, &vValue, 0, VT_R8)) && sValue.Find(’.’) != -1); <br>if(bStrIsFloat) <br>{ <br>AfxMessageBox("点"); <br>} <br>} <br><br>6Q如何徏立一个UNICODE应用E序Q?<br><br>建立一个应用程序,打开Alt+F7 settings选项Q选择C/C++选项卡,在Preprocessor definenation中加上_UNICODEQ在Link选项卡中Q在Category选择框中选择OutputQ在Entry-point symbol~辑框中Q添加wWinMainCRTStartup定?<br><br>注意调试UNICODEE序Ӟ需要在安装时VC选择所有选项Q否则会~少动态库和相应的.lib文g <br><br><br>7QADO操作数据库表Q更新出现问?<br>在打开数据库前Q添加如下语句试一下pRecordSet->CursorLocation = adUseClient</div> </td> </tr> </tbody> </table><img src ="http://m.tkk7.com/dongwq/aggbug/135099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2007-08-07 23:16 <a href="http://m.tkk7.com/dongwq/archive/2007/08/07/135099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Knowing something of everything and everything of something. 通百专一ѝ?/title><link>http://m.tkk7.com/dongwq/archive/2007/08/07/135098.html</link><dc:creator>强摩羯?/dc:creator><author>强摩羯?/author><pubDate>Tue, 07 Aug 2007 15:12:00 GMT</pubDate><guid>http://m.tkk7.com/dongwq/archive/2007/08/07/135098.html</guid><wfw:comment>http://m.tkk7.com/dongwq/comments/135098.html</wfw:comment><comments>http://m.tkk7.com/dongwq/archive/2007/08/07/135098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/dongwq/comments/commentRss/135098.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/dongwq/services/trackbacks/135098.html</trackback:ping><description><![CDATA[     摘要:   指针的类?x针本w的cd)和指针所指向的类型是两个概念。当你对C来熟悉时Q你会发玎ͼ把与指针搅和在一L"cd"q个概念分成"指针的类??指针所指向的类?两个概念Q是_N指针的关键点之一。我看了不少书,发现有些写得差的书中Q就把指针的q两个概忉|在一起了Q所以看起书来前后矛盾,看糊涂?  <a href='http://m.tkk7.com/dongwq/archive/2007/08/07/135098.html'>阅读全文</a><img src ="http://m.tkk7.com/dongwq/aggbug/135098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/dongwq/" target="_blank">强摩羯?/a> 2007-08-07 23:12 <a href="http://m.tkk7.com/dongwq/archive/2007/08/07/135098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://cjsyw123.com" target="_blank">Ʒۺվ</a>| <a href="http://7778kk.com" target="_blank">þþƷƷް </a>| <a href="http://cc88899.com" target="_blank">ѹۿaƵ</a>| <a href="http://hezuoedu.com" target="_blank">߹ۿվ</a>| <a href="http://fense1.com" target="_blank">**һëƬ</a>| <a href="http://wwwfafa98.com" target="_blank">ÿµavƬ߹ۿ</a>| <a href="http://234an.com" target="_blank">4399Ӱѹۿֱ</a>| <a href="http://masfd.com" target="_blank">ԻȫƵվ</a>| <a href="http://6ork.com" target="_blank">8xվ߹ۿ</a>| <a href="http://xianzznn.com" target="_blank">˳ɶ߲r18 </a>| <a href="http://jgc528.com" target="_blank">޹˾Ʒþ</a>| <a href="http://kyqp0022.com" target="_blank">91Ƶ߹ۿ</a>| <a href="http://by22877.com" target="_blank">¶ۺƵ</a>| <a href="http://slmlxg.com" target="_blank">޹ƷAV</a>| <a href="http://sijep.com" target="_blank">Ʒþþþ</a>| <a href="http://fholaer.com" target="_blank">޳ַ</a>| <a href="http://1880531.com" target="_blank">avƷר߹ۿ</a>| <a href="http://dazngt.com" target="_blank">С˵ͼƬQVOD</a>| <a href="http://5g6z.com" target="_blank">޳aƬ߹ۿձ</a>| <a href="http://266hd.com" target="_blank">avպƬ߹ۿ</a>| <a href="http://cuuka.com" target="_blank">һɫݳѾƷվ</a>| <a href="http://8953y.com" target="_blank">18ڵվ</a>| <a href="http://zhuoyueyc.com" target="_blank">һëƬѿ</a>| <a href="http://njchxf.com" target="_blank">ëƬڵ߳</a>| <a href="http://viviker.com" target="_blank">ĻӰԺ߲</a>| <a href="http://tiantangapp.com" target="_blank">ԻȫƵվ</a>| <a href="http://www779rr.com" target="_blank">Ѹ弤Ƶ</a>| <a href="http://vinsotec.com" target="_blank">߿Ƭa</a>| <a href="http://langse3.com" target="_blank">˳ۺ</a>| <a href="http://xvwenyue.com" target="_blank">ۺϾþþƷ </a>| <a href="http://fcw70.com" target="_blank">100018Ƶ</a>| <a href="http://b2bautoparts.com" target="_blank">Ʒ10000</a>| <a href="http://dsfv1.com" target="_blank">ݹѾþþ91</a>| <a href="http://726kxw.com" target="_blank">ѹۿƵվ</a>| <a href="http://kssijia.com" target="_blank">Ļwww˳</a>| <a href="http://cuuka.com" target="_blank">Ʒ޸һ </a>| <a href="http://kyqp0022.com" target="_blank">˳Ƶ߹ۿƵ</a>| <a href="http://ytsp88.com" target="_blank">þþþþþ91Ʒѹۿ</a>| <a href="http://88bgbg.com" target="_blank">Ұ¾þø</a>| <a href="http://gujingyuye.com" target="_blank">þþƷA㽶</a>| <a href="http://dddd20.com" target="_blank">ѲŴɫaƵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>