<!-- generator=" CodePongo (Base on Kukkaisvoima version 15b3TA)" -->
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel><title>CodePongo: cplusplus</title><link>http://codepongo.com/blog</link><description></description><pubDate>Fri, 09 Sep 2016 17:30:06 +0200</pubDate><lastBuildDate>Fri, 09 Sep 2016 17:30:06 +0200</lastBuildDate><generator>http://codepongo.com/blog</generator><language>zh-cn</language><item><title>编写C++C代码规则
</title><link>http://codepongo.com/blog/3qapHQ</link><comments>http://codepongo.com/blog/3qapHQ#comments</comments><pubDate>Fri, 09 Sep 2016 17:30:06 +0200</pubDate><dc:creator>zuohaitao</dc:creator><category>cplusplus</category><guid isPermaLink="false">http://codepongo.com/blog/3qapHQ/</guid><description><![CDATA[ 
 [...]]]></description><content:encoded><![CDATA[


2007年01月15日 星期一 12:44

编写C++/C代码规则
参考书目《高质量C++/C编程》（林锐著）
能长期稳定地编写出高质量程序的程序员称为编程老手。
能长期稳定地编写高难度高质量程序的程序员称为编程高手。
※知错就改；温故知新；坚持学习，天天向上
规则
★为了防止头文件重复引用，应当用ifndef/define/endif结构产生预处理块。
★用include表示引用标准库的头文件；用include "filename.h"引用非标准库的头文件。
？★头文件只存放“声明”而不存放“定义”；不提倡使用全局变量，不要在头文件声明，分目录放置；如果头文件是私有的，为加强其隐蔽性，存放在子目录中。

★类声明之后，每个函数定义之后都要加空行。
★逻辑密切相关的不加空行，其他的地方应加空行。
★一行代码只做一件事。
★if，for，while，do等语句各自占一行，执行语句不得紧跟其后。无论执行语句有多少都要加{}。
★变量定义时初始化。
★关键字之后要留空格，函数名之后不留空格。
★“{”和“}”独占一行与引用它们的语句左对齐。
★“{}”内语句在右边数格处左对齐。
★代码行（hang）为一屏幕能显示下的长度。
★长代码表达式在低优先级操作符处拆分成新行，操作符放在新行之首（以便突出操作符）。拆分出的新行要进行适当缩进，使排版整齐语句可读。
×将修饰符*和&紧靠变量（不同意！既然都不允许int* x,y的声明方式，为何不靠近数据类型！）
★注释是代码提示，不是文档（象我，在没有条件写文档的情况下只能拿注释当文档！）注释与代码一直，没用的注释及时删除。注释放在代码上方！
★★尽量使结构清晰，避免繁琐的注释。
★★多重嵌套结束处加注释，便于阅读。
★★标识符应当直观可拼读，长度应符合“min-length&&max-informatrion”原则。
★★与所采用的OS或开发工具的风格保持一致。
★不要靠大小写区分相似的标识符。
★★不要出现完全相同的局部变量和全局变量。
★变量名使用“形容词+名词”。
★★全局函数名使用“动词”+“名词”；类成员函数名只使用“动词”。
★★用正确的反义词表互斥的变量或相反的动作函数。
★windows程序开发“匈牙利”命名规则
  类名和函数名首字母大写
  变量和参数用小写字母开头的单词组合而成
  常量全部大小用下划线分割单词
  静态变量s_，全部变量g_，类的类数据成员m_。
★★对于unsigned的变量加入un前缀，对于常用的，并且通过变量名称如：(size len 等)容易推断出的变量不加前缀
★代码行中符号较多，用括号确定其优先级。
★复合表达式不要太复杂，不要多用途，不要与数学表达式混淆。
★不可将布尔变量与TRUE，FALSE或者1，0进行比较。
★将整形变量用“==”或“！=”直接与0比较。
★不可将浮点变量用“==”或“！=”与任何数字比较。
★指针变量用“==”或者“！=”与NULL比较。
★if的条件可写成if(NULL == p)，注意。
=、 ★注意使用其简单模式：condition?x:y。
★★长循环在最内，会提高循环效率。
★逻辑判断套循环效率高，但不易理解，不易修改。
★★不可在循环体内改变循环变量。
★for循环采用半开半闭区间写法for(i=0;i★每个case语句后都要加break。
★不要忘记default分支。
★多重嵌套可使用goto跳出。
★★函数很多返回，且返回之前要释放堆上申请的内存或关闭文件等操作，可使用goto返回位置。
★★使用含义直观的常量表示程序中多次出现的数字或字符串。
×在C++中只使用const不使用#define。
★需要对外公开的常量放在头文件中，不需要公开的放在定义文件的头部；用户看得见的放在一个公共的头文件中，便于管理。
★★定义中应表现出关系密切的常量间的关系。
★类中常量应用enum{SIZE1=100, SIZE2=200}。
★参数的书写要完整（类型 名字）；无参数应写void（声明中用void）。
★★参数要命名恰当，顺序合理。
★如果参数是指针，且反作输入用，应在类型前加const，以防在函数内被修改。
★值传递，传递对象时应用const& 方式省去临时对象的构造和析构过程，提高效率。
★★参数最好控制在五个以内，尽量不使用类型和数目不确定的参数。
★不要省略返回值类型。
★★函数名和返回值在语义上不可冲突。
★返回对象时使用“引用传递”可提高效率，但有些场合会出错。
★★在函数体的“入口处”对参数的有效性进行检查—正确使用断言(assert)。在函数体的“出口处”对return语句的正确性和效率进行检查。不能返回指针“栈内存”的“指针”或引用 返回的是“值”，“指针”还是“引用”。返回值是个对象，要考虑return的效率。
★★函数应功能单一，50行代码以内，避免“记忆”（static）功能，检查全局变量，文件句柄等，出错处理的返回值一定要清楚。
★★assert不仅说明非法错误还要说明非法错误的原因！
★★对参数合法性的判断：assert()只适用自己和团队内部调用的函数，是一种“约定”的检查，对外提供的函数接口不应使用assert()，应用if替代。

内存分配方式：静态存储区域，在栈上创建，从堆上分配。
内存错误以及对策：内存未分配成功却使用它，使用之前检查指针是否为NULL
分配成功却未初始化却使用了；赋初值
忘记释放内存，new/delete malloc/free成对出现
释放了却还使用：数据结构不合理，重新设计；return用错；野指针
修改指向静态存储区的指针中的内容将出错
数组用库函数strcpy()，strcmp()进行复制和比较
指针内容比较，先申请len+1个空间内存在用strcpy比较 sizeof(数组)计算数组的容量sizeof(指针)计算指针变量的容量 数组作为函数的参数进行传递时，数组自动退化为同类型指针，不要用指针参数申请动态内存，如果必须应用指向指针的指针 指针与其所指向的内存的消亡是没有联系的
new/delete对对象比malloc/free多调用构造和析构函数
内存耗尽指针将返回NULL；用return返回；用exit(1)终止程序
异常处理如 vc++中_set_new_hander函数？
malloc的使用：int* p = (int *)malloc(sizeof(int) * length);
free的使用free(NULL)没有问题，free(p)且p!=NULL二次将出错
new数组对象时，delete[]数组释放
重载 小心隐式类型转换
重载，隐藏，覆盖
参数缺省值只出现在函数声明中，多个缺省值从后向前挨个缺省
重载运算符
×内联取代宏代码，内联放定义处；代码长，有循环不易inline。inline会对栈溢出的排错造成困难
一定要写无参数构造函数，拷贝构造函数，析构函数，赋值函数，偷懒时候可将其声明为private
若逻辑上B是A的“一种”，并且A的所有功能和属性对B而言都有意义，则允许B继承A的功能和属性
use const whenever you need!


]]></content:encoded><wfw:commentRss>http://codepongo.com/blog/3qapHQ/feed/</wfw:commentRss></item><item><title>﻿为什么C++标准模板库中的std::map是红黑树而不是哈希表？
</title><link>http://codepongo.com/blog/3hqZ0j</link><comments>http://codepongo.com/blog/3hqZ0j#comments</comments><pubDate>Thu, 21 Jul 2016 17:30:06 +0200</pubDate><dc:creator>zuohaitao</dc:creator><category>cplusplus</category><guid isPermaLink="false">http://codepongo.com/blog/3hqZ0j/</guid><description><![CDATA[ 
 [...]]]></description><content:encoded><![CDATA[
原文

红黑树与哈希表比较：


哈希表操作不够清楚。
红黑树插入，删除，查找速度可均摊。
在最坏情况下，树有更好的性能。


这大半是因为一个历史意外。在标准规则被确定之前，标准容器（包括迭代器和算法）很晚才被加入。所以，在标准确定之前，没有充分考虑到哈希表的定义，并且也没有足够时间加入。所以标准只包括了一个基于树的map。

C++11 加入了基于hash的std::unorderedmap（以及std:unorderedset)。



]]></content:encoded><wfw:commentRss>http://codepongo.com/blog/3hqZ0j/feed/</wfw:commentRss></item><item><title>《Essential C++》笔记
</title><link>http://codepongo.com/blog/40nEoG</link><comments>http://codepongo.com/blog/40nEoG#comments</comments><pubDate>Fri, 10 Jun 2016 17:30:06 +0200</pubDate><dc:creator>zuohaitao</dc:creator><category>cplusplus</category><guid isPermaLink="false">http://codepongo.com/blog/40nEoG/</guid><description><![CDATA[ 
 [...]]]></description><content:encoded><![CDATA[

2007年01月15日 星期一 12:33

快速学习C++

其中*为需要重点注意
《Essential C++》侯捷译 Stanley B. Lippman著

一、C++基础
 1、撰写C++程序
 ////////////////////////////////////////
 #include 
 using namespace std; //让命名空间暴光
 int main
 {
   cout }
 ///////////////////////////////////////
 如果main()函数的最后没有return语句，C99规定编译器要自动在生成的目标文件中（如 exe 文件）加入return 0;表示程序正常退出。
 2、对象的定义与初始化 ？？※const的应用
 3、撰写表达式
 4、条件语句和循环(Loop)语句
  if (条件)
  {
   ...
  }
  else
  {
   ...
  }
  while (条件)
  {
   ...
  }
 5、数组 Arrays off-by-one 越界(数组array[n]从array[0]开始，最后一个为array[n-1])
 6、指针带来的弹性 *取值 &取地址
 7、文件的读写
  #include 
  ofstream outfile ("seq_data.txt"); //写文件
  ofstream outfile("seq_data.txt", ios_base::app); //追加形式开启
  ifstream infile("seq_data.txt"); //读文件
  fstream iofile("seq_data.txt", ios_base::in|ios_base::app); //读写

二、面向过程的编程风格
 1、撰写一个函数
  int function(int x, int *y)
  {
    ...
    return 0;
  }
 2、调用(invoking)一个函数
 3、提供默认参数值
 4、使用局部静态对象 const
 5、声明一个inline函数
 6、提供重载函数
 7、定义并使用模版函数
  template
  int function(const int x, const elemtype y)
  {
    ...
  }
 8、函数指针 vector* (*seq_pstr)(int);
 9、枚举类型 enum ns_type{ns_fibon, ns_lucas, ns_pell};
 10、设定头文件

三、泛型编程风格
 1、指针的算术运算 int* pi;pi+2的意义
 2、???Iterators泛型指针
  vector svec;
  vector::iterator iter=svec.begin();
 3、所有容器通用的操作
  equality() ==
  inequality() !=
  assignment() =
  empty()
  size()
  clear()
  begin()
  end()
  insert()
  erase()
 4、使用序列式容器
 5、使用泛型算法
 6、如何设计一个泛型算法
 （1）开始我们写了一个函数，它可以找出vector内小于10的所有元素，然而函数过于死板没有弹性。
 （2）接下来我为函数加上一个数值参数，让用户得以指定某个数值，以此和vector中的元素做比较。
 （3）后来我又加上一个新函数:一个函数指针，让用户得以指定比较方式。
 （4）然后我引入function object的概念，使我们得以将某组行为传给函数，此法比函数指针的做法效率更高，我们也带领各位简短地检阅了标准函数库提供的function object(所谓function object，是某种class的实体对象，这类classes对function call运算符进行了重载操作，如此一来，可使function object被当成一般函数来使用)[函数指针，指向函数]
 （5）最后我们以template function的形式重新实现。为了支持多种容器，我们传入一对iterators，标出一组元素的范围；为了支持多种元素型别，我将元素型别参数化也将施用于元素身上的“比较操作”参数化，以便得以同时支持函数指针和function object两种方式
 3、TMap使用
  map words;
  words["verneer"] = 1;
  map::iterator it;
first;
second;
  words.find(); //如果key已置于其中，find()会返回一个iterator，指向key/value形成一个pair；反之则返回end()
  words.count(); //返回某特定项目在map内的个数
 set 由一群keys组合，对于任何keys值，set只能存储一份
  set iset
   iset.insert(ival);
   iset.insert(vec.begin(), vec.end());
 如何使用Iterator Inserters
  #include 
  back_inserter();
  inserter(vector, iterator);
  front_inserter();

四、基于对象的编程风格
 1、如何实现一个class
 class Jack
 {
 public:
  //...
 private:
 //...
 }
 2、constructor和destructor
 3、const
 4、this指针
 5、static class member静态的类成员 类名::静态成员函数
 6、iterator class
 7、friend class友元类
 8、copy assignment operator
 9、function object
 10、运算符重载
 11、指向类成员函数的指针
五、面向对象编程风格
 （1）概念：继承、多态、动态绑定
 （2）面向对象思维
 （3）不带继承的多态*
每个操作行为的存取层次(是public还是private还是protected)
 （5）定义一个派生类*
 （6）使用继承体系：将所有派生类共有的实现内容抽离出来，移至基类内
 （7）基类抽象：从子类中抽象出基类
 （8）初始化、析构、复制 子类数据成员=基类data member+本身data member
派生时完全吻合
 （10）执行期型别鉴定机制*

六、以template进行编程
 1、被参数化的型别
 2、class template的定义
 3、template型别参数(type parameters)的处理
 4、实现一个class template
 5、一个以function template完成的output运算符
 6、常量表达式（constant expressions）默认参数（Default Parameters）
 7、Template参数
 8、member template funtions

七、异常处理*
]]></content:encoded><wfw:commentRss>http://codepongo.com/blog/40nEoG/feed/</wfw:commentRss></item><item><title>C++函数声明中带用throw关键字
</title><link>http://codepongo.com/blog/1aA1cr</link><comments>http://codepongo.com/blog/1aA1cr#comments</comments><pubDate>Fri, 13 May 2016 17:30:06 +0200</pubDate><dc:creator>zuohaitao</dc:creator><category>cplusplus</category><guid isPermaLink="false">http://codepongo.com/blog/1aA1cr/</guid><description><![CDATA[ 
 [...]]]></description><content:encoded><![CDATA[
function declaration with throw


void f() throw() // no exceptions allowed 不允许抛出任何异常
void f() throw(...) // all exceptions allowed 允许抛出任何异常
void f() throw(type) // only the exception of type type allowed 只允许抛出type类型的异常


]]></content:encoded><wfw:commentRss>http://codepongo.com/blog/1aA1cr/feed/</wfw:commentRss></item><item><title>可单独使用的MFC基础类
</title><link>http://codepongo.com/blog/2TkGKs</link><comments>http://codepongo.com/blog/2TkGKs#comments</comments><pubDate>Fri, 10 Jan 2014 17:30:06 +0200</pubDate><dc:creator>zuohaitao</dc:creator><category>cplusplus</category><category>windows</category><guid isPermaLink="false">http://codepongo.com/blog/2TkGKs/</guid><description><![CDATA[ 
 [...]]]></description><content:encoded><![CDATA[
从visual C++.NET 2002(VC 7.0)开始，一些存在于MFC的基础类被重写和修订，削减了与
其他MFC类之间的关系。这些类库可以独立被用于任何的native C++工程。

类


CFileTime
CFileTimeSpan
CFixedStringT
CImage
COleDateTime
COleDateTimeSpan
CPoint
CRect
CSimpleStringT
CSize
CStrBufT
CStringData
CStringT
CTime
CTimeSpan
IAtlStringMgr



CSimpleStringT
 |
 +--CStringT
     |
     +--CFixedStringT


测试代码

例子

https://github.com/codepongo/utocode/tree/master/windows/independentmfc


int 
main(int argc, char* argv[])
{
    /* string */
 str;
    str = "hi";
    str += ",independent MFC!\n";
    printf(str);


    /* point size rect */
    CPoint pt;
    CRect rc;
    CSize sz;
    rc.left = rc.top = 0;
    rc.right = rc.bottom = 100;
    sz = rc.Size();
    pt.x = 10;
    pt.y = 10;
    printf("rect(%d, %d, %d, %d):(%d,%d) move (%d, %d)\n",
        rc.left, rc.top, rc.right, rc.bottom, sz.cx, sz.cy, pt.x, pt.y);

    /* time */
    CTime tms;
    CTime tm;
    str.Format("%04d-%02d-%02d %02d:%02d:%02d\n",
        tms.GetYear(), tms.GetMonth(), tms.GetDay(), tm.GetHour(), tm.GetMinute(), tm.GetSecond());
    printf(str);

    CFileTime ft;
    CFileTimeSpan fts;
    COleDateTime dt;
    COleDateTimeSpan dts;

    str.Format("%lld\n", ft.GetTime());
    printf(str);

    /* image */
    CImage image;
    image.Load(L"image.png");
    str.Format("width:%d height%d\n", image.GetWidth(), image.GetHeight());
    printf(str);

    system("pause");
    return 0;
}




参考

ATL/MFC Shared Classes

Classes Shared by MFC and ATL

MFC Hierarchy Chart

CString模板结构解析

]]></content:encoded><wfw:commentRss>http://codepongo.com/blog/2TkGKs/feed/</wfw:commentRss></item></channel></rss>