命令
GDB 是 Linux 下的命令行调试工具。
启动 GDB 有如下几种方式:
gdb <program>
直接启动执行程序
gdb <program> core
用gdb 同时调试一个可执行程序和core文件。core 是程序非法执行后 core dump 产生的文件
gdb <program> <PID>
指定进程, gdb会自动 attach 上去。program 应该在 PATH 环境变量中可以搜索得到。
常用的 gdb 命令如下
信息 info
info 可以简写成 i
info args
列出参数
info breakpoints
info break
i b
列出所有断点
info break number
i b number
列出序号为 number 的的断点
info watchpoints
i watchpoints
列出所在 watchpoints
info threads
列出所有线程
inifo registers
列出寄存器的值
info set
列出当前 gdb的所的设置
i frame
i stack
i locals
i catch
断点和监视 break
& watch
继续阅读
memcpy
和 memmove
都可用于复制一段内存。
它们之间的区别很简单:
memmove
更安全:当源内存块和目标内存块存在重叠区域时,memcpy
的行为是未定义的。它可能崩溃或产生错误数据。而且在debug 和 release 模式下的表现各不相同。
memcpy
更快。
这是两种不同编程思想的实现。一种更注重安全, 一种更注重效率。
下面是两个方法可能的实现方式.
继续阅读
Cookie
指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据,它是一种古老的技术, 由网景公司的前雇员卢·蒙特利在1993年3月发明。
Cookie 格式是一系列键值对, 以 ;
组合,如下
|
TBLkisOn=0; GeoIP=US:CA:Los_Angeles:34.05:-118.26:v4; mwPhp7Seed=9d0 |
当然, Cookie还有更多的内容,如创建时间,过期时间等,对应的域等等。一般而言,为了安全只允许页面访问该域下的Cookie.
根据 Cookie 的时效性可以将 Cookie 分为两类,一种是会话型Cookie (Session Cookie), 只保存于内存中, 当浏览器退出的时候,即清除这些 Cookie. 第二种是持续型 Cookie (Persistent Cookie),也就是当浏览器退出的时候仍然保留的Cookie.
Chromium 中Cookie操作的类结构如下所示: 
其中 CookieStore
是主要的导出接口,CookieMonster
是重要的实现接口,它相当于是 Cookie 的管理器。它有几个作用:一是实现 CookieMonster
中的接口,二是报告前者的事件,如 Cookie 更新信息等,三是 Cookie对象(即 CanonicalCookie
) 的集合。
PersistentCookieStore
持久化类,SQLitePersistentCookieStore
是持久化的具体实现,负责实际的存储动作。
Chrome 的 Cookie使用 Sqlite存储,是位于 %AppData%\Local\Google\Chrome\User Data\Default
目录下的 Cookies
文件。
继续阅读
这一章谈 C++11 中引入的两种 “语法糖” .使用它们可以使得我们的代码更为简洁优雅。
委托构造函数
在同一个类中,一个构造函数可以调用另一个构造函数,这叫委托构造函数。这是 C++ 11 的新特性。
委托构造函数可以简化在每个构造函数中的重复代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class B{ public: B():x_(0),y_(0),z_(0){ //Do something } B(int x): B(){ x_ = x; } B(int x, int y): B(x){ y_ = y; } void DoSomething(){} private: int x_; int y_; int z_; }; |
注意一点,委托构造函数在使用时不可以形成环:禁止套娃。
继续阅读
这一章聊一聊在面向对象的C++中,构造函数的调用顺序。
数据成员的构造顺序
一个类的数据成员的初始化顺序只与其在类中的声明顺序相关,与其它无关。
而析构时,如果成员是在堆中,析构顺序正好与构造时相反。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
class M { public: M(const char* msg) { cout << "M " << msg << endl; msg_ = new char[strlen(msg)+1]; msg_[strlen(msg)] = '\0'; strcpy(msg_, msg); } ~M() { cout << "~M " << msg_ << endl; delete msg_; } private: char* msg_; }; class A { public: A() : pm2_(new M("pm2")), m2_("m2"), pm1_(new M("pm1")), m1_("m1") {} private: M m1_; M m2_; M* pm1_; M* pm2_; }; int main() { A a; return 0; } |
类A的成员的构造顺序为: m1_, m2_, pm1_, pm2_
。析构时的顺序为 m2_, m1_
,由于 pm1_, pm2_ 不在堆中,所以它们的析构需要类A自己管理。
继续阅读
三五零法则
我们知道,编译器会为类自动生成几个特别的成员函数:构造函数、复制构造函数、复制赋值运算符、析构函数。后三者比较特殊,我们在下面会频繁提到。
三法则
若一个类需要用户显式定义 析构函数、复制构造函数、复制赋值运算符 中的一个,那么这三个函数都需要显式定义 。如果用户显式定义了其中一个,另外两个还是会被编译器隐式定义,这种混杂的情况容易生产无法预期的错误。
如果一个类中有非基本数据类型或者非类类型的成员(如指针、文件描述符等),则这一法则表现的更为明显:隐式析构函数无法对这种成员进行有效的释放,隐式复制构造函数和隐式复制赋值运算符无法进行深拷贝。
继续阅读
C++ 构造函数有很多有意思的小细节。这里来做一些探讨。这些内容可能会分为几章,这一章来探讨 隐式构造函数,显式空构造函数 和 =default 修饰的构造函数 ,私有构造函数和 =delete 修饰的构造函数 之间的区别。
在开始之前,我们先了解两种特殊的类:
聚合类 与 POD
聚合类
是 C++ 中的一个特殊的类型。当一个类(class, struct, union) 满足以下条件时,它是一个聚合类:
- 无显式声明的构造函数(可以是
default
或 delete
的)
- 无基类
- 无虚成员函数
- 无私有的或受保护的非静态数据成员
- 无使用
{}
或 =
直接初始化的非静态数据成员
一个普通数组也是一种聚合类型(如 int[10], char[], double[2][3])
POD
( Plain old data structure ) 则是一种特殊的聚合类,它必须满足聚合类的所有条件,且不具有以下成员:
- 指针到成员类型的非静态数据成员(包括数组)。
- 非POD类类型的非静态数据成员(包括数组)。
- 引用类型的(reference type)非静态数据成员。
- 用户定义的拷贝与赋值算子。
- 用户定义的析构函数。
可见,POD类类型就是指class、struct、union,且不具有用户定义的构造函数、析构函数、拷贝算子、赋值算子;不具有继承关系,因此没有基类;不具有虚函数,所以就没有虚表;非静态数据成员没有私有或保护属性的、没有引用类型的、没有非POD类类型的(即嵌套类都必须是POD)、没有指针到成员类型的(因为这个类型内含了this指针)
POD 一般用来在不同的模块之前传递数据使用。如一个 C++ 库向外提供 C 接口,可以使用 POD 作为参数。
隐式构造函数,显式空构造函数 和 =default
修饰的构造函数。
对于 未定义任何构造函数 的类型( struct
class
or union
),编译器会为该为自动生成一个 inline public 的构造函数, 如果这个类型满足 constexpr 类型的要求,则这个构造函数还会被 constexpr 修饰,这个由编译器生成的构造函数,我们称之为 隐式构造函数 或 默认构造函数。在 C++11 以前,如果用户声明了其它构造函数,则编译器不会生成默认构造函数,需要我们显式的声明。而在 C++11 以后,我们仍可用 default
关键字来强制编译器自动生成原本隐式声明的默认构造函数。
继续阅读
项目中发现使用个别机器的 IE 访问某些个别页面出现 500 错误。分析发现出现错误的机器,其 IE 的 HTTP RequestHeader Accept-Language 是 zh-Hans-CN
, 而正常的机器是 zh-CN
. 由于某些原因无法修改服务器程序,那只能强制修改 IE 的 header.

方式是修改注册表:
计算机\HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\International
,
添加或修改项 AcceptLanguage
为 zh-CN
, 重启 IE 即可。
常见的中文语言标签
- zh-Hans 简体中文
- zh-Hans-CN 大陆地区使用的简体中文
- zh-Hans-HK 香港地区使用的简体中文
- zh-Hans-MO 澳门使用的简体中文
- zh-Hans-SG 新加坡使用的简体中文
- zh-Hans-TW 台湾使用的简体中文
- zh-Hant 繁体中文
- zh-Hant-CN 大陆地区使用的繁体中文
- zh-Hant-HK 香港地区使用的繁体中文
- zh-Hant-MO 澳门使用的繁体中文
- zh-Hant-SG 新加坡使用的繁体中文
- zh-Hant-TW 台湾使用的繁体中文