摘要: 恼人的函数指针(一)这篇是为了加深记忆所写。发现,很多知识若不经过反复的琢磨和动手实践,是很难记得住的。1) 函数指针的初始化。函数如下:1intCompareString(conststring&str1,conststring&str2)2{3returnstr1.compare(str2);4}函数的初始化有两种方式:第一种,也是最普遍的方式:1int(*CompareFunction)(conststring&,conststring&)=CompareString;第二种,是使用typedef定义函数类型,这种写法有助于对代码的理解:1typedefi 阅读全文
posted @ 2013-05-25 10:37 Jerry19880126 阅读(264) 评论(0) 推荐(0) 编辑
摘要: 一般函数指针和类的成员函数指针转载请注明原文网址:http://www.cnblogs.com/xianyunhe/archive/2011/11/26/2264709.html函数指针是通过指向函数的指针间接调用函数。函数指针可以实现对参数类型、参数顺序、返回值都相同的函数进行封装,是多态的一种实现方式。由于类的非静态成员函数中有一个隐形的this指针,因此,类的成员函数的指针和一般函数的指针的表现形式不一样。1、指向一般函数的指针函数指针的声明中就包括了函数的参数类型、顺序和返回值,只能把相匹配的函数地址赋值给函数指针。为了封装同类型的函数,可以把函数指针作为通用接口函数的参数,并通过函数 阅读全文
posted @ 2013-05-25 10:28 Jerry19880126 阅读(322) 评论(0) 推荐(0) 编辑
摘要: 从这个条款开始,就进入到资源管理部分了。资源管理往往是大型项目的一个难点,也是重中之重,看到一些编程规范,都是将资源管理的规范列为高优先级的重点。管理资源的最好方法其实是预防,而好的预防方法就是尽量不去使用C/C++的原生指针,这些指针像幽灵一样,一个“忘记”,就是一个隐患。当项目小的时候,这些隐患看不出来,但当研发一个拥有上万级用户的产品时,服务器对很多人同时运行含有隐患的代码,这个隐患就会爆发,导致内存不足而崩溃。举个例子,初学者常常这样写:1 int *p = new int();2 …3 delete p;这个当然是OK的,内存可以回收,但万一中间的过程超过数十行,你还能记住去dele 阅读全文
posted @ 2013-05-19 09:03 Jerry19880126 阅读(864) 评论(0) 推荐(0) 编辑
摘要: 这句话包含两部分的意思:第一部分是要考虑到所有成员变量,特别是后加入的,相应的拷贝构造函数和赋值运算符要及时更新;第二部分是在存在继承时,不要遗忘基类部分的复制。先看第一部分的意思,举个例子:1 class SampleClass2 {3 private:4 int a;5 public:6 SampleClass(const SampleClass& s):a(s.a)7 {}8 };这里只举了一个拷贝构造函数的例子,赋值运算符与之类似,如果这个时候又加了一个成员变量,比如double b,拷贝构造函数和赋值运算符就要相应地更新(构造函数... 阅读全文
posted @ 2013-03-21 15:35 Jerry19880126 阅读(1185) 评论(2) 推荐(0) 编辑
摘要: 直观的operator=是这样定义的: 1 class SampleClass 2 { 3 private: 4 int a; 5 double b; 6 float* p; 7 public: 8 SampleClass& operator= (const SampleClass& s) 9 {10 a = s.a;11 b = s.b;12 p = s.p;13 ... 阅读全文
posted @ 2013-03-21 10:03 Jerry19880126 阅读(3905) 评论(1) 推荐(0) 编辑
摘要: 这个条款很简单的说,先解释一下为什么赋值后还要有返回值,这是因为我们可以这样用连等:1 int x, y, z;2 x = y = z;注意等号是右结合的,所以上述运算实际上等同于:x = (y = z);如果没有返回值,上述代码就不能通过编译。至于为什么返回的是一个引用,这并不是编译器强制的,但有三个原因让你觉得这样做是明智的:(1) 返回引用可以节省资源,不必要为返回值调用构造函数了;(2) 形如(x = y) = 3这样的连等,编译器也能接受了,因为这样的写法要求赋值运算符返回的是可以修改的左值;(3) STL和boost库中的标准代码都是这样写的,为了与它们相兼容,还是放弃你的标新立异 阅读全文
posted @ 2013-03-20 23:15 Jerry19880126 阅读(1109) 评论(2) 推荐(0) 编辑
摘要: 先举一个在构造函数中调用virtual函数的例子: 1 class Base 2 { 3 public: 4 Base() 5 { 6 VirtualFunction(); 7 } 8 9 virtual void VirtualFunction()10 {11 cout << "In the Base Class" << endl;12 };13 };14 15 16 17 class Derived: p... 阅读全文
posted @ 2013-03-19 17:19 Jerry19880126 阅读(1115) 评论(0) 推荐(1) 编辑
摘要: 举书上的例子,有以下代码: 1 class Widget 2 { 3 public: 4 ~Widget(){…} // 析构函数 5 }; 6 7 void DoSomething() 8 { 9 vector<Widget> v;10 }STL的vector在析构时会逐一调用容器内每个元素的析构函数,这样问题就来了,万一在Widget的析构函数里出现了异常,又没有及时地在析构函数中处理这个异常,导致异常被抛出,因为vector中存在多个Widget元素,这样在析构时就会多次抛出未处理的异常,多个异常同时存在是非常危险的,它会导致不明确的行为。最好的解决... 阅读全文
posted @ 2013-03-19 10:45 Jerry19880126 阅读(890) 评论(0) 推荐(0) 编辑
摘要: 严格来说,多态分为编译时多态和运行时多态,编译时多态是函数的重载,而运行时多态则是迟绑定技术,即根据基类指针或引用的实际指向来决定采取何种行动,一般来说,多态特指运行时多态。下面我们来举有关C++多态的一个简单例子: 1 class Shape 2 { 3 private: 4 int color; 5 public: 6 virtual void print() = 0; 7 }; 8 9 10 class Circle: public Shape11 {12 private:13 double radius;14 public:15... 阅读全文
posted @ 2013-03-18 16:36 Jerry19880126 阅读(1795) 评论(0) 推荐(1) 编辑
摘要: 举个书上的例子,地产中介商卖的是房子,有这样一个类:class HomeForSale{…}每个房子都是不一样的,所以希望这样:1 HomeForSale house1;2 HomeForSale house2;3 HomeForSale house3(house1); // house3企图与house1相同,不能通过这种情况4 house2 = house1; // house2也不应该与house1相同,也不能通过这种情况我们希望最后这两句话不能通过编译,那么怎样在C++中实现呢?一种想当然的做法,就是不去写拷贝构造函数和赋值运算符。但由上一个条款可以知道,这样做是行不通的,C++编译器 阅读全文
posted @ 2013-03-17 19:50 Jerry19880126 阅读(1250) 评论(1) 推荐(2) 编辑