c/c++
文章平均质量分 51
lifu119
这个作者很懒,什么都没留下…
展开
-
关于串口的操作
sigh。。。杯具的串口停止位没有设置对。花了我一晚上时间。。原因竟然是停止位设置错了。所以每次连接串口后必须通过串口调试工具打开一次,软件才能运行正常。好好总结下,串口的操作。为了使软件对任意一台电脑都使用,采用轮询每个串口COM1~COM20,若打开COMi成功,则向串口发送读取状态指令,若读取结果正常,则当前串口对应着下位机。1.为了响应要求,加入进度条,进度条对应着初始化的原创 2012-09-03 00:49:40 · 2747 阅读 · 0 评论 -
effective C++笔记之条款27:如果不想使用隐式生成的函数就要显示地禁止它
l 习惯应该坚持下去,不管今天是什么日子。来自3月17日晚上9点半的总结。l 比如类模板Array,它所生成的类除了可以进行上下限检查外,其他行为和C++标准数组一样,但标准的数组是不允许数组间赋值的。设计中面临的一个难题是怎样禁止掉Array对象间的赋值操作。l 有如下两步禁止隐式生成的函数生成:声明这个函数(如operator=),并使原创 2012-03-17 21:43:44 · 886 阅读 · 0 评论 -
effective C++笔记之条款41、42: 区分继承和模板、明智地使用私有继承
条款41:区分继承和模板l 模板类的特点:行为不依赖于类型l 当对象的类型不影响类中函数的行为时,就要使用模板来生成这样一组类。(堆栈类型)因为堆栈类型中,即使你对堆栈中的成员类型T一无所知,还是能够写出每个成员函数,stack的行为在任何地方都不依赖于T。l 当对象的类型影响类中的行为时,就要使用继承来得到这样一组类。(猫的类型)因为原创 2012-04-02 17:16:27 · 8346 阅读 · 0 评论 -
effective C++笔记之条款26:当心潜在的二义性
三种可能的情况1.类中构造函数与重载转换运算符间的二义性,如下所示:class B;class A{public: A(const B& b) { cout << "A()" << endl; }private: int data;};class B{public: B():data(0) {} operator A() const;private: i原创 2012-03-16 16:13:14 · 1042 阅读 · 2 评论 -
effective C++笔记之条款24、25:在函数重载和设定参数缺省值间慎重选择、避免指针和数字类型重载
条款24:在函数重载和设定参数缺省值间慎重选择l 会对函数重载和设定参数缺省值产生混淆的原因在于,他们都允许一个函数以多种方式被调用。l 到底用哪个取决于两个问题。确实有那么一个值可以作为缺省吗?要用到多少种算法?一般来说,如果可以选择一个合适的缺省值并且只是用到一种算法,就使用缺省值,否则,就用函数重载。l 设定参数缺省值原创 2012-03-15 15:09:29 · 932 阅读 · 0 评论 -
effective C++笔记之条款22:尽量使用“传引用”而不用“传值”
l 通过值来传递一个对象的具体含义是由这个对象的类的拷贝构造函数定义的。这使得传值成为一种非常昂贵的操作。为避免这种潜在的昂贵的开销,就不要通过值来传递对象,而要通过引用。这会非常高效,因为没有新的对象被创建。而且避免了“切割问题”。如下所示:class Window{public: sting name() const; virt原创 2012-03-14 21:25:45 · 921 阅读 · 0 评论 -
effective C++笔记之条款23:必须返回一个对象时不要试图返回一个引用
l 想要返回一个对象的引用时,重载乘号操作符容易犯以下几个错误,:1 返回一个局部对象的引用2 在堆上创建一个对象,然后返回它的引用,无法去delete它,造成内存泄漏3 返回静态对象的引用,导致两个不同对象的==操作符总是为真。l 所以正确的乘法操作符应该返回一个新对象。这会导致operator的返回值构造和析原创 2012-03-14 21:34:33 · 1462 阅读 · 0 评论 -
effective C++笔记之条款20、21:避免public接口出现数据成员、尽可能使用const
条款20: 避免public接口出现数据成员 l 如果接口里存在数据成员,用户每次访问类的成员时候会想是该用括号还是不该用括号。如果每个成员都是函数,就不用多想了。l 采用函数可以更精确地控制数据成员的访问权。如果使数据成员为public,每个人都可以对它读写;如果用函数来获取或设定它的值,就可以实现禁止访问、只读访问和读写访问、只写访问。l原创 2012-03-13 17:13:16 · 916 阅读 · 0 评论 -
effective C++笔记之条款19:分清成员函数,非成员函数和友元函数
这是很重要的一个条款。l 成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不行。所以,如果有个函数必须进行动态绑定,而虚拟函数必定是某个类的成员函数。但如果函数不必是虚拟的,情况就稍微复杂一点。l 只要能避免使用友元函数就要避免,因为,和现实生活中差不多,友元(朋友)带来的麻烦往往比它(他/她)对你的帮助多。 l 结论如下原创 2012-03-12 14:57:11 · 1184 阅读 · 0 评论 -
effective C++笔记之条款18:争取使类的接口完整并且最小
l 类的用户接口是指使用这个类的程序员所能访问得到的接口。典型的接口里只有函数存在,因为在用户接口里放上数据成员会有很多缺点。l 一个完整的接口是指那些允许用户做他们想做的任何合理的事情的接口。l 一个最小的接口,是指那种函数尽可能少、每两个函数都没有重叠功能的接口l 大的类接口缺点:1 接口函数越多,以后的潜在原创 2012-03-12 14:55:14 · 556 阅读 · 0 评论 -
effective C++笔记之条款16: 在operator=中对所有数据成员赋值
1. 写赋值运算符时,必须对对象的每一个数据成员赋值。每增加一个数据成员,同时要更新构造函数和赋值运算符。2. 对于指针成员,赋的值是指针所指的值,而不是指针本身。3. 涉及继承时,应注意Base成员的赋值操作。如下情况:class Base{public: Base(int temp = 0):x(temp) {}pr原创 2012-03-11 14:23:47 · 705 阅读 · 0 评论 -
effective C++笔记之条款40: 通过分层来体现“有一个”或“用…来实现”
分层:使某个类的对象成为另一个类的数据成员,从而实现将一个类构筑在另一个类之上,这一过程称为“分层”。公有继承的含义是“是一个”。对应地,分层的含义是“有一个”或“用…来实现”。Person对象“有一个”名字,地址,电话号码和传真号码。Set模板要求用来表示任意对象的集合,并且集合中没有重复元素。因为list可以包含重复对象,所以,用公有继承不行,因为Set“是一个”list是错误的,他不能包含重原创 2012-03-28 10:56:24 · 2985 阅读 · 0 评论 -
effective C++笔记之条款15:让operator=返回*this的引用
l 缺省版本的operator=函数具有如下形式:C&C::operator=(const C&);l 返回值常犯的错误:返回void,妨碍了连续赋值操作;返回const对象的引用,使该语句不能通过(w1 = w2)= w3。l 即使重载了赋值操作符,返回的也是类的对象的引用。如标准string类型提供了两个不同版本的赋值运算符,如下所示:原创 2012-03-11 14:02:21 · 777 阅读 · 0 评论 -
effective C++笔记之条款39: 避免“向下转换”继承层次
先看如下例子:class Person {…};class BankAccount{public: BankAccount(const Person *primaryOwner, const Person *jointOwner); virtual ~BankAccount(); virtual void makeDeposit(原创 2012-03-27 16:15:00 · 2898 阅读 · 0 评论 -
effective C++笔记之条款43: 明智地使用多继承(MI)
l 多继承带来了单继承中绝对不会存在的复杂性。最基本的一条是二义性。如果一个派生类从多个基类继承了一个成员名,所有对这个名字的访问都是二义的;你必须明确地说出你所指的是哪个成员。如下所示:class Lottery{public: virtual int draw(); ...};class GraphicalObject{public:原创 2012-04-04 15:21:03 · 2814 阅读 · 0 评论 -
effective C++笔记之条款28: 划分全局名字空间
l 全局空间最大的问题在于它本身仅有一个。在大的软件项目中,经常会有不少人把他们的定义放在这个单一的名字空间中,从而不可避免地导致名字冲突。l 解决方法:可以在全局符号前加上一些不大可能造成冲突的前缀。 另一个比较好的方法就是使用 C++ namespace 。namespace本质上和使用前缀的方法一样,只不过避免了别人总是看到前缀而已。用户可以通过三种方原创 2012-03-19 09:00:42 · 751 阅读 · 0 评论 -
vector源码
vector 源码// Filename: stl_vector.h /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentat原创 2012-08-22 00:23:38 · 14651 阅读 · 0 评论 -
pthread_cond_signal和pthread_cond_wait简介
pthread_cond_wait() 用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread_cond_s转载 2012-08-10 13:36:57 · 2502 阅读 · 0 评论 -
函数调用栈
理解调用栈最重要的两点是:栈的结构,EBP寄存器的作用。首先要认识到这样两个事实:1、一个函数调用动作可分解为:零到多个PUSH指令(用于参数入栈),一个CALL指令。CALL指令内部其实还暗含了一个将返回地址(即CALL指令下一条指令的地址)压栈的动作。2、几乎所有本地编译器都会在每个函数体之前插入类似如下指令:PUSH EBP; MOV EBP ESP;即,在程序执行到一个函数原创 2012-08-06 19:22:38 · 2378 阅读 · 0 评论 -
WaitForMultipleObjects返回值得问题
如果因时间终了而返回,那返回值是WAIT_TIMEOUT 如果bWaitAll是TRUE,那么返回值是WAIT_OBJECT_0 如果bWaitAll是FALSE,那么返回值减去WAIT_OBJECT_0,就表示哪一个handle被激发了 如果函数失败,则返回WAIT_FAILD,这时候你可以用GetLastError()找出失败原因 bWaitAll 为第三个参数原创 2012-07-17 12:57:15 · 6479 阅读 · 0 评论 -
effective C++笔记之条款47: 确保非局部静态对象在使用前被初始化
非局部静态对象的定义:定义在全局或名字空间范围内;在一个类中被声明为static;在一个文件范围内被定义为static。当一个对象的初始化要依赖于另一个被编译单元中的另一个对象的值,并且这第二个对象本身也需要初始化,事情就会变得复杂。因为对于不同编译单元的非局部静态对象,无法控制初始化的顺序。我们可以访问具有与非局部静态对象“相似行为”的对象(不存在初始化问题)。这种技术称原创 2012-04-18 17:01:19 · 3040 阅读 · 0 评论 -
effective C++笔记之条款46: 宁可编译和链接时出错,也不要运行时出错
只要有可能,就要让出错检查从运行时退回到链接时,或者,最理想的是编译时。这种方法带来的好处不仅仅在于程序的大小和速度,还有可靠性。通常,对设计做一点小小的改动,就可以在编译期间消除可能产生的运行时错误。如下所示的类:class Date{public: Date(int data, int month, int year);} 要实现这个构造原创 2012-04-16 21:07:15 · 2579 阅读 · 0 评论 -
effective C++笔记之条款33: 明智地使用内联
l 内联函数的基本思想在于将每个函数调用以它的代码体来代替。这种做法很可能会增加整个目标代码的体积。在一台内存有限的计算机里,过份地使用内联所产生的程序会因为有太大的体积而导致可用空间不够。过多的使用内联还会降低指令高速缓存的命中率,从而使取指令的速度降低,因为从主存取指令当然比从缓存要慢。l 另一方面,如果内联函数非常短,编译器为这个函数体生成的代码就会真的比为函原创 2012-03-21 19:29:21 · 964 阅读 · 0 评论 -
effective C++笔记之条款45: 弄清C++在幕后为你所写、所调用的函数
如果没有声明下列函数,编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值操作符,一个析构函数,一个取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。当需要的时候需要,这些函数就会被生成。生成的这些函数中:缺省构造函数和析构函数实际上什么也不做,它们只是让你能够创建和销毁类的对象。(33,M24)。生成的析构函数一般是非虚拟的原创 2012-04-08 16:50:32 · 2828 阅读 · 1 评论 -
effective C++笔记之条款44: 说你想说的;理解你所说的
总结:1. 共同的基类意味着共同的特性。如果类D1和类D2都把类B声明为基类,D1和D2将从B继承共同的数据成员和/或共同的成员函数;2. 公有继承意味着“是一个”。如果类D公有继承于类B,类型D的每一个对象也是一个类型B的对象,但是反过来不成立;3. 私有继承意味着“用..来实现”。如果类D私有继承于类B,类型D的对象只不过是用类型B的对象来原创 2012-04-08 16:17:40 · 2717 阅读 · 0 评论 -
effective C++笔记之条款31、32: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针所指对象的引用、尽可能地推迟变量的定义
条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针所指对象的引用。l 返回一个局部对象的引用。局部对象在被定义时创建,在离开函数体时被销毁。当函数返回时,程序的控制离开了这个空间,所以函数内部所有的局部对象被自动销毁。因此,如果返回局部对象的引用,那个局部对象其实已经在函数调用者使用它之前被销毁了。l 返回函数内部用new初始化的指针原创 2012-03-20 20:02:01 · 1860 阅读 · 0 评论 -
effective C++笔记之条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但成员的访问级比这个函数要低。
有如下三种情况:1.class Address { …};class Person{public: Address& personAddress() { return address; }private: Address address;}; Person scott(..);Address& addr = scott.personA原创 2012-03-19 20:47:52 · 1164 阅读 · 0 评论 -
effective C++笔记之条款29: 避免返回内部数据的句柄
const A a;是否会变化?答案取决于其成员函数的组成结构。先看一个String类:class String{public: String(const char *value); ~String(); operator char *() const; //转换String到char *private: c原创 2012-03-19 15:47:22 · 871 阅读 · 0 评论 -
effective C++笔记之条款17: 在operator=中检查给自己赋值的情况
l 注意别名:同一个对象有两个以上的名字。别名可以以大量任意形式的伪装出现,所以在写函数时一定要考虑到它。l 在赋值运算符要特别注意可能出现的别名的情况,有两个理由:1. 效率。如果可以在赋值运算符函数体的首部检测到是给自己赋值,就可以立即返回,从而可以节省大量的工作,否则必须去实现整个赋值操作。2. 更重要的原因。一个赋值运算符原创 2012-03-11 14:38:38 · 885 阅读 · 0 评论 -
effective C++笔记之条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
l 当类里有指针,并且需要动态分配时,如果没有定义自己的拷贝构造函数和赋值操作符,使用编译器合成的缺省的操作,将会带来一些严重的后果,如内存泄漏(调用赋值操作符时)、调用两次delete(如以类对象进行传值调用、调用拷贝构造函数时)。l 用delete去删除一个已经被删除的指针,其结果是不可预测的。l 只要类里有指针,就要写自己版本的拷贝构造函数和原创 2012-03-09 12:55:51 · 1041 阅读 · 1 评论 -
如何判断一段程序是由C编译,还是由C++编译?
用判断宏的方式。大多数编译器在编译时如果是c++的程序都会定义一个叫_cplusplus的宏。因此可以用这段代码来判断若包含的头文件是stdio.h则用这段代码#ifdef __cplusplus printf("c++%c");#else printf("c%c");#endif若包含的是头文件iostream.h,则用这段原创 2012-02-15 09:27:48 · 3225 阅读 · 0 评论 -
++运算符 前置、后置 对应的汇编语言,了解整个内部过程
a = b = ++c + (d++);◆ 前缀运算符在所有计算之前进行,后缀运算符则在(所有)赋值之后进行。 这是因为整个表达式中赋值运算符优先级是最低的,因此该运算符代表的全部操作完成后,整个表达式也就差不多运算结束了,故我们可以这样记忆:◆ 前缀运算符最先算,后缀运算符最后算。对应的汇编代码:0041417A mov eax,原创 2012-02-20 17:34:28 · 1699 阅读 · 1 评论 -
vc6.0 项目头文件、动态链接库设置
参考http://www.cnblogs.com/hongzg1982/archive/2011/04/20/2022298.html1、项目包含头文件设置通过Project->settings->c/c++完成,再选择Category下的Preprocessor。Preprocessor:预编译处理。我们可以在这里预先定义一些宏名,指定部分或所有符号具有未定义状态。Addit原创 2011-12-29 10:34:04 · 2328 阅读 · 2 评论 -
网络字节序与主机字节序
总结不错的一篇文章不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序.最常见的有两种1. Little endian:将低序字节存储在起始地址2. Big endian:将高序字节存储在起始地址LE little-endian最符合人的思维的字节序地址低位存储值的低位地址高位存储值的高位怎么讲是最符合人的思维转载 2012-02-20 23:24:00 · 414 阅读 · 0 评论 -
STL实现的底层数据结构简介
C++ STL 的实现:1.vector 底层数据结构为数组 ,支持快速随机访问2.list 底层数据结构为双向链表,支持快速增删3.deque 底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问4.stack 底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限转载 2012-02-20 23:21:51 · 856 阅读 · 0 评论 -
C++运算符重载转换运算符
为什么需要转换运算符? 大家知道对于内置类型的数据我们可以通过强制转换符的使用来转换数据,例如(int)2.1f;自定义类也是类型,那么自定义类的对象在很多情况下也需要支持此操作,C++提供了转换运算符重载函数,它使得自定义类对象的强转换成为可能。 转换运算符的生命方式比较特别,方法如下: operator 类名(); 转换运算符的重载函数是没有返回类型转载 2012-02-15 14:52:44 · 662 阅读 · 0 评论 -
C++开发必看 四种强制类型转换的总结
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。 const_cast,字面上理解就是去const属性。 static_cast,命名上理解是静态类型转换。如int转换成char。 d原创 2012-02-14 17:22:22 · 581 阅读 · 0 评论 -
scanf与printf转换说明符区别
【问题描述】 scanf函数与printf函数的转换说明符几乎一致,都可以使用%c,%d,%e,%f,%g,%a,%p,%o等。那么他们的转换说明符有何区别?【解析】printf函数中将%f,%e,%E,%g,%G同时用于float类型和double类型,而scanf只把它们用于float类型,而用于double类型时要求使用l修饰符,即使用类似于%le的转换说明符。这就意味着,如果将pr转载 2012-02-13 12:53:52 · 698 阅读 · 0 评论 -
关于数组名应该注意的
数组名的本质如下:(1)数组名指代一种数据结构,这种数据结构就是数组;例如:char str[10];cout << sizeof(str) << endl;输出结果为10,str指代数据结构char[10]。(2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;char str[10];str++; //编原创 2012-02-11 11:41:01 · 465 阅读 · 0 评论 -
[C/C++] float和double类型的内存分布和比较方法
C/C++的浮点数据类型有float和double两种。类型float大小为4字节,即32位,内存中的存储方式如下: 符号位(1 bit)指数(8 bit)尾数(23 bit)类型double大小为8字节,即64位,内存布局如下:符号位(1 bit)指数(11 bit)尾数(转载 2012-01-04 22:08:47 · 2450 阅读 · 0 评论