Thrift是facebook的开源RPC库,对于网络方面,我已有自己还算成熟的网络库,所以我把Thrift当作一个序列化库使用 (为什么不使用google-protobuffer?那是因为Thrift的官方多语言支持)。 在使用Thrift的过程中,遇到了一些问题,就例如enum类型不能嵌套使用。其实enum不能嵌套使用是挺不方便的, 前几天在做游戏服务器端时就遇到这个问题。 因为游戏中有一些实体(如玩家、npc、宠物等),这些实体有很多属性(血量、法力、速度等),而这些属性需要被各种 子模块(如技能、任务、AI等)存取,最重要的一点是要被脚本进行存取,所以我把这些实体定义为以下形式。 struct FieldsType { enum type { HP = 0, MAXHP, POWER, MAXPOWER, SPEED, MAX, }; }; class Role { public: Role(); ~Role(); // Get and set. core::uint32 GetAttribute(core::uint16 type); void SetAttribute(core::uint16 type, core::uint32 value); private: core::uint32 fields_[FieldsType::MAX]; }; 而对于这种方式的属性,子模块进行访问就很方便了。 Skill::Attack(core::uint64 src_id, core::uint64 dest_id, core::uint32...
Read more.
February 8, 2013 | thrift | comments
使用vim自动生成文件头只需要在.vimrc文件中增加以下代码即可: map <F4> :call TitleDet()<CR> function AddTitle() call append(0, "\/\/") call append(1, "\/\/ Summary: buzz source code.") call append(2, "\/\/") call append(3, "\/\/ Author: Tony.") call append(4, "\/\/ Email: tonyjobmails@gmail.com.") call append(5, "\/\/ Last modify: ".strftime("%Y-%m-%d %H:%M:%S".".")) call append(6, "\/\/ File name: ".expand("%:t")) call append(7, "\/\/") call append(8, "\/\/ Description:")...
Read more.
January 15, 2013 | vim | comments
编码中需要清楚地区分这两个概念,这也是容易引起错误的地方,以下是具体说明: // 这里datas是一个const char *指针数组,其实应该理解为一个一维数组,每个元素是一个指针。 void Function(const char *const *datas, const size_t size) { for(size_t pos = 0; pos < size; ++pos) { // 这里是每个元素的值是一个char *指针。 printf("%s\t", datas[pos]); } } int main(void) { char data[2][10] = { "1", "2" }; // 这里使用一个二维数组来强转成一个指针数组,这样是有问题的。 // 强转后,元素个数还是两个,但每个元素的值本来是一个字符串,现在这个值被强转为了一个指针, // 把一个数值转换成一个指针,必然是一个不合法的指针,使用就会崩溃。 Function((const char *const *)data,...
Read more.
October 29, 2012 | c_cpp | comments
不管有没有继承与成员对象,永远都是先调用本类的构造函数的。
只是在构造函数内部,执行第一个有效语句之前,会先调用基类的构造函数,再调用成员对象的构造函数,最后再执行本类构造函数内部的语句。
而构造函数内部做得事情包含(通常的实现是按这个顺序的):
初始化this指针。 2. 调用基类构造函数。 3. 初始化虚表指针(虚表是编译是建立的,虚表指针需要在构造时赋值)。 4. 调用成员对象的构造函数。 5. 执行构造函数内的语句。
需要注意的是,初始化虚表指针的时机在C++标准里是没有明确的规定的,所以 3 可能会被编译器实现放到 5 的后面。
由于这个原因C++标准明确规定了,在构造函数内,不允许发生多态的行为,也就是说如果有虚函数,必须要调用当前构造函数类的那个虚函数(即在基类构造函数中会调用基类的函数,在子类构造函数中会调用子类的函数)。
Read more.
June 16, 2012 | c_cpp | comments
无数的coder这样写:
char *pointer = new Object;
if(pointer == NULL) {
return false;
}
而其中判断指针为NULL的这句是一句无效地判断,因为如果分配失败,STL会抛出异常,这段代码没有捕获异常,所以会core dump了。
让new操作符失败时不抛出异常:
char *pointer = new (std::nothrow) Object;
Read more.
May 16, 2012 | c_cpp | comments
大概的意思是发生中断,没有找到设备。
先用命令cat /proc/interrupts 看一下中断,看出错的IRQ号对应的设备是不是有多个,如果有多个,把他们分开。
cat /var/log/messages 看下系统日志,有什么提示,有可能会给出解决方向。
内核启动参数上加入irqpoll: 打开文件vim /boot/grub/menu.lst 在kernel /vmlinuz-2.6.32-220.el6.x86_64 这行,加入参数irqpoll,需要reboot系统。
也有可能是其他设备的irq被错误的路由到了8139too的中断处理程序,可能是其他设备本身或者driver的问题。
检查一下BIOS的IRQ设定看看。
Read more.
April 18, 2012 | c_cpp | comments
运行时如果报错类似于:
无法解析的外部符号 "unsigned short __cdecl number_nxlh<unsigned short>(unsigned short,int,int,
class boost::shared_ptr<class std::vector<unsigned char,class std::allocator<unsigned char> > >)"
(??$number_nxlh@G@@YAGGHHV?$shared_ptr@V?$vector@EV?$allocator@E@std@@@std@@@boost@@@Z),
该符号在函数 "public: virtual void __thiscall SCMD60000Node::deserialize(class boost::shared_ptr<
class std::vector<unsigned char,class std::allocator<unsigned char> > >)"
(?deserialize@SCMD60000Node@@UAEXV?$shared_ptr@V?$vector@EV?$allocator@E@std@@@std@@@boost@@@Z) 中被引用
一般是调用时找不到定义。
一般编译器编译代码时,只看声明,不看定义,而连接的时候,一般都可以报错,但有一种情况在C++中是不会报错的,就是在virtual函数中调用一个函数时,连接是不检查的。
一般来说,编译器编译代码时只检查是否声明,连接时才使用类似于符号表去找连接的目标,而由于virtual函数是动态绑定的,可能在连接时并不去寻找连接的目标,应该他本身可能找不到的。
看报错的是一个模板函数找不到定义,再看调用的时候是virtual函数调用的,再联想到大多数编译器是不支持模板的分离编译的,就知道问题所在了。
Read more.
April 13, 2012 | c_cpp | comments
使用方法: valgrind –tool=memcheck –leak-check=yes –log-file=分析结果文件名 –tool=memcheck表示使用memcheck检测各种非法的内存访问。 –leak-check=yes表示检测内存泄漏。 一些错误提示的解释: 提示错误:Conditional jump or move depends on uninitialised value(s): 不一定是错误,更多的可能是有变量没有做初始化,一般就在函数堆栈的最后一层会找到未初始化的变量。 提示错误:24 bytes in 1 blocks are definitely lost in loss record 14 of 75: 应该是进行了动态内存的申请,但没有释放。 提示错误:Source and destination overlap in memcpy(0x7fefff910, 0x7fefff910, 15): 应该是在memcpy时,源地址和目的地址有重叠,改用memmove就可以解决。 提示错误:Invalid read of size 4…中间是一些堆栈…Address 0x559a9f0 is 1,792 bytes...
Read more.
March 22, 2012 | memory | comments
运行以下程序:
#include <thread>
#include <iostream>
void my_thread_func()
{
std::cout<<"hello"<<std::endl;
}
int main()
{
std::thread t(my_thread_func);
}
提示错误为:
terminate called without an active exception hello 已放弃
考虑应该是主线程结束了子线程还没有结束导致的。
应该在main函数中增加:
t.join();
Read more.
March 22, 2012 | c_cpp | comments
This is a introduction about me, My name is Tony, I’m a programmer and I program in Linux platform using C/C++ language.
Follow me in weibo.com.
Have a nice day!
Read more.
January 1, 2011 | aboutme | comments