你确定你懂 Const 和 Mutable ?

const 和 mutable 是 C++ 中两个关键字,你确定你懂 const 和 mutable 吗?

下面是一段完整的 C++11 代码;

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <utility>
#include <future>
#include <vector>
using namespace std;
vector<int> v(1000);
int main()
{
  auto x = async([]{ pair<int, vector<int>> z{1, v}; });
  auto y = async([]{ pair<int, vector<int>> z{2, v}; });
  x.wait();
  y.wait();
  return 0;
}

上面的程序能正确同步么? 有线程安全的问题吗?

嗯, vector 是标准库的内置容器, 如果换成我们自己写的类呢? 比如下面的代码;

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <utility>
#include <future>
using namespace std;
class widget {/*...*/} w1, w2;

int main()
{
  auto x = async([]{ pair<widget, widget> z{ w1, w2 }; });
  auto y = async([]{ pair<widget, widget> z{ w1, w2 }; });
  x.wait();
  y.wait();
  return 0;
}

widget 的线程安全性如何?

Read on →
C++

C++11 Lambda in Qt5

C++11 发布已经1年多,各家编译器也都有了很好的支持,新特性中有非常多值得关注的东西,比如:右值引用、类型推导、匿名函数等等。

lambda 函数与表达式

C++11 引入了 lambda 函数,在函数是 first class 的语言中,匿名函数是最基础的设施,可以方便的运用闭包造出高阶函数。现在 C++11 引入了 lambda 表达式(是不是可以在 C++ 中玩 Functional Programming 了,嘿嘿),和标准库算法配合起来就不会像以前那么别扭了。在没有 lambda 的时候使用 std::sort 或者 std::find 时,需要一个具名函数,原本一个很简单的,用完就丢掉的代码段必须声明为一个函数或仿函数,割裂了逻辑不说,还占用了一个标识符(取名,在写代码的时候时很让人头疼的一件事,你懂的),现在一切都变的简单了。

Read on →
C++, Qt

[译] Why C++ Is Not Back

前言:这个月初,Herb Sutter 发了一篇名为 Perspective: “Why C++ Is Not ‘Back’”,的文章,虽然 Sutter 不同意原文中的全部细节,但也推荐读一读原文和评论。语言之争,由来已久,每次一有这种文章就会引发激烈的讨论,比如这里

本译文中不会发表任何观点,尽量表达原作者的意图,如有翻译不当的地方欢迎大家积极指出,我会做出修改。

原文在这里: Why C++ Is Not “Back”

下面是译文:

我喜爱 C++。

C++ 真正教会了我如何写代码。

以前,我会学习语言本身的复杂性,STL,以及内存管理和指针运算中的所有细节。

这些都是很美好的时光。我还记得一遍又一遍的读 Scott MeyersEffective C++ 系列。每一次都能从中学到一些新的东西,或者更理解如何使用 C++。

我说上面这些只是想让你知道,我不讨厌 C++。我喜欢 C++。

我知道,有很多优秀现在仍然在使用 C++ 并教别人如何使用,这一点也没有错。

但问题是什么?

Read on →
C++

CMake Lua 5.2

不知道从什么时候开始,lua 源码不再提供 visual studio 工程文件了。windows 用户只能自己动手了,无奈 visual studio 版本太多,工程文件也不是人能读懂,简直不可维护。所以下面用 CMake 来生成 vcproj,这样维护起来更方便。

什么是 CMake?

CMake 是个开源的跨平台自动化建构系统,它用组态档控制建构过程(build process)的方式和 Unix 的 Make 相似,只是 CMake 的组态档取名为 CMakeLists.txt。CMake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。

有了 CMake 就不用在 vcproj 的各个版本之前来回的切换了,每次用 CMake 生成相应的工程文件就一切 OK 了。

Windows 下用 CMake 安装 lua 5.2.1

安装 CMake

官方下载相应的安装包,安装完成后,别忘了把 CMake 加入 PATH 中。

使用 CMake 生成 vcproj

lua官方不提供带 CMake 的源码,会的朋友可以手工写几个 CMakeList.txt 就 OK,不会的直接下载 bitdewy 写好的 cmake-lua-5.2.1.tar.gz 吧。解压后用 visual studio 的命令行进入 lua-5.2.1/build 目录,然后输入:

1
cmake -DCMAKE_INSTALL_PREFIX="C:\lua52" ..

完成之后就可以打开 build 目录下的 lua.sln 文件直接编译了,编译 INSTALL 工程,会在上面设置的 C:\lua52 目录中安装 lua,luac,静态链接库,动态链接库,头文件、源代码以及文档,如果不想安装,不编译 INSTALL 工程就好。如果不设置安装目录,那么 windows 下默认的安装目录就是 %ProgramFiles%

COM、ABI与引用计数

什么是 COM ?

Component Object Model (COM) 组件对象模型,是微软 1993 年引入的软件组件的二进制接口标准。它可以让多种编程语言之间可以相互通信,动态的创建对象。详细内容请看 Component Object Model

什么是 ABI ?

Application Binary Interface (ABI) 应用二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低层接口。

ABI涵盖了各种细节,例如:

  • 数据类型、大小以及内存布局
  • 调用约定(控制着函数的参数如何传送以及如何接受返回值)
  • 系统调用的编码和一个应用如何向操作系统进行系统调用
  • 在一个完整的操作系统ABI中,目标文件、程序库的二进制格式等等。

一个完整的ABI,像Intel二进制兼容标准(iBCS),允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。

其他的ABI标准化细节包括C++ name mangling、异常传播,同一个平台上的编译器之间的调用约定,但是不包括跨平台的兼容性。详细内容请看 Application binary interface

Read on →
C++, COM

Xcode 配置 Qt 开发环境手记

首先,这是一个奇葩的需求,不要问为什么不用 Qt Creator,为什么不用 qmake + make,没有那么多为什么。

其次,准备好 Xcode 先。正文开始:

安装Qt library

Qt5 已经发布 RC1 版本,不过还没到不影响正常使用的程度,所以还是先用 4.8.4,下载链接点这里,MAC 版的 release 和 debug 库是分开的,可以自由选择。一路安装,下一步就 OK。

Read on →

Hello All

Hello world, new github blog;

一级标题

二级标题

三级标题

四级标题

五级标题
六级标题

这是一个引用

引用中的引用

这是一个超链接

下面是一个list:

  • 第一条
  • 第二条
  • 第三条

斜体还是斜体粗+斜粗体

后面是代码-> something.excute(); <– 前面是代码

下面是一段代码:

1
2
3
4
5
6
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while b < 10:
    print b
    a, b = b, a+b

最后来一张八爪萌猫大图:

Read on →

Unix 的隐藏文件是个 Bug

玩过 Unix/Linux 的人应该都知道,在 *nix 文件系统中,以.开始的文件(夹)是隐藏文件(夹),但你可能想不到这是一个设计上的 bug。

8月份的时候,Rob Pike 在 Google+ 上发了一篇名为 “A lession in shortcuts” 的短文,介绍了 Unix 文件系统中隐藏文件这个设计上的 bug (feature)。

在 Unix 文件系统设计的早期,为了导航更方便而引入了 ...。当用户输入 ls 时会列出文件清单,所以 KenDennis 添加了一些简单的代码。当时用的是汇编,不过代码看起来应该是像这样的:

1
2
if (name[0] == '.')
    continue;

这比它应有的样子稍微短了一点点:

1
2
if (strcmp(name, ".") || strcmp(name, "..") == 0)
    continue;

嘿,这很简单。

Read on →

C++ ORM 框架 ODB

什么是 ORM?

对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。如今已有很多免费和收费的ORM产品,而有些程序员更倾向于创建自己的ORM工具。

面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。

简单的说:ORM相当于中继数据。通俗的说,ORM就是将对象和它们之间的关系映射成关系数据库的表,以及在数据库中它们的关系。目标就是确定一种持久化对象数据的有效策略,在考虑类之间继承结构的同时,存储各个对象的数据属性和对象间的关系。

Read on →
C++, ORM

C++11 Std::unordered_map

历史

在 C++ 中,第一个被广泛使用的哈希表实现是 SGI STL 中的,hash_map, hash_set, hash_multimap, hash_mutiset。 由于哈希表是非常常用的数据结构,逐渐的各厂家实现的标准库中都引入了该数据结构。

例如,GCC 的 lisbstdc++ , 以及微软的 MSVC 标准库。在这些公用的名字后面,有不同的实现,呃,不同的实现。它们在接口、能力、内在数据结构和支持操作的相关效率方面不同。写出使用哈希表的可移植代码是可能的,但不可能像使用标准库中的容器一样容易。(知道标准的重要性了吧。)好在 hash_* 这一组类加入了 C++ TR1 , 可惜由于名字被非标准的各家实现占用,只能退而求其次,改名为 unordered_*

C++11 中,不排序的关联容器已经正式进入标准库。现在再选择的话,可以毫不犹豫的放弃非标准的 hash_* 而选择标准库中的 unordered_* 系类了。boost <boost/unordered_map.hpp> 中同样有实现。

Read on →