摘要:
这个条款从字面意思上理解很简单,很多程序都是这样做的,即使作为初学者,也知道该将成员变量声明为private,但有没有想过,为什么要这样做?为什么public成员变量不行?protected成员变量行不?举一个简单的例子:1 class Clothes2 {3 public:4 int price;5 string name;6 };假设有一个衣服的类,里面的成员变量用来描述它的价格和衣服名。将之设为public的话,类外可以直接接触到price成员变量。这样很危险,因为客户端可以直接修改price了,卖衣服的商家就会不开心了。而将price设置成private,像这样: 1 ... 阅读全文
摘要:
当你理解条款21后,很可能出现一种过度使用的情况:只要看到是一个非内置类型,就去使用引用传值。举个书上的例子:1 class Rational2 {3 private:4 int numerator;5 int denominator;6 public:7 Rational():numerator(0), denominator(1){}8 friend const Rational& operator* (const Rational& r1, const Rational& r2){…}9 };numerator表示分子,denominator表示分母,这里... 阅读全文
摘要:
默认情况下,C++的函数调用是传值调用,也就是说形参拷贝实参的内容。举书上的例子: 1 class Person 2 { 3 private: 4 string name; 5 string address; 6 public: 7 Person(){} 8 virtual ~Person(){} 9 };10 11 class Student: public Person12 {13 private:14 string schoolName;15 string schoolAddress;16 public:17 Student(){}... 阅读全文
摘要:
这里初看到”class”和”type”,感觉他们是说的是同一样东西,但仔细读了一下,两者在文中还是有区别的。class侧重于自定义的类,而type侧重于系统预定义的类(像int、double、string、vector)。设计好的class,使之像设计type一样,就是说要使自己设计的类像系统预定义的类那样好用,这对设计思想提出了较高的要求。要设计高效的class,需要回答以下的问题:1. 对象如何去创建和销毁?这是构造函数和析构函数的问题,当然如果想要有堆分配方式,还需要重载new、new[]、delete和delete[]运算符;2. 对象初始化与对象的赋值应该有什么样的差别?初始化是构造 阅读全文
摘要:
从本条款开始,就进入到全书的第四部分:设计与声明。程序员设计接口时应本的对用户负责的态度,“如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码不应该通过编译;如果代码通过了编译,那它的作为就该是客户所想要的”。举一个书上的例子:1 class Date2 {3 public:4 Date(int month, int day, int year);5 …6 };这个类看上去好像没有问题,提供的构造函数接口简单直观,然而它却做了一个假设——用户都能够按月、日、年的顺序来传参。但事实上,一定会有不少用户记错这个顺序,比如我们常用的顺序是年、月、日,所以有同学会下意识地这样... 阅读全文
摘要:
举书上的例子:1 int GetPriority();2 void processWidget(shared_ptr<Widget> pw, int priority);如果这样调用processWidget:processWidget(new Widget(), GetPriority());注意一下两边的类型,左边是管理者shared_ptr<Widget>类,而右边是被管理者Widget类,两边类型不等,编译器会试图执行类型隐式转换,但为了安全起见,shared_ptr的构造函数前面有修饰符explicit,它不允许发生隐式转换,所以编译器会报错。但如果这样:pr 阅读全文
摘要:
这个条款比较好理解,就是new有两种形式:1 int *p = new int(); // 申请一个int资源2 int *p = new int[3]; // 申请连续三块int资源而delete也有两种资源:1 delete p; // delete指针所指向的单一资源2 delete [] p; // delete指针所指向的多个连续资源块那么该各用哪一种形式呢?一个简单又好记的规则就是:在new如果使用了[],那么delete也去用[];反之则都不用。一句话,都用或者都不用。但事实上,如果用错了,编译器不会给任何提示,也没有运行错(VS2008环境),这些行为是“未定义的”。这可能会产 阅读全文
摘要:
先放上自己写的MySharedPtr类,这是仿照shared_ptr的功能来实现的(实际shared_ptr要复杂的多)。 1 #ifndef MY_SHARED_PTR_H 2 #define MY_SHARED_PTR_H 3 4 #include <iostream> 5 using namespace std; 6 7 8 typedef void (*FP)(); 9 10 template <class T>11 class MySharedPtr12 {13 14 private:15 T *ptr;16 size_t *count;17 F... 阅读全文
摘要:
条款十四:在资源管理类中小心copying行为首先来看一个例子: 1 #include <iostream> 2 using namespace std; 3 4 class Lock 5 { 6 public: 7 explicit Lock(int* pm): m_p(pm) 8 { 9 lock(m_p);10 }11 12 ~Lock()13 {14 unlock(m_p);15 }16 17 private:18 int *m_p;19 void lock(int* pm)20 ... 阅读全文
摘要:
恼人的函数指针(二):指向类成员的指针前面曾写过一篇恼人的函数指针(一),总结了普通函数指针的声明、定义以及调用,还有函数指针数组,函数指针用作返回值等。但是作为C++的研读,我发现我漏掉了一个最重要的内容,就是指向类成员的指针,这里将做相应补充(相关代码测试环境为vs 2010)。指向类成员的指针总的来讲可以分为两大类四小类(指向数据成员还是成员函数,指向普通成员还是静态成员),下面一一做介绍:一、指向类的普通成员的指针(非静态)1、指向类成员函数的指针简单的讲,指向类成员函数的指针与普通函数指针的区别在于,前者不仅要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型。总 阅读全文