在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data = a.data*b.data;//a,b的成员变量相乘 return temp; } 既然栈空间不行,试试堆空间 friend A& operator*(const A& a, const A& b) { A *temp=new A; temp.data = a.data*b.da…
从本条款开始,就进入了全书的第七部分:模板与泛型编程.模板与泛型在C++中是非常重要的部分,还记得本书第一章时,把C++视为一个联邦,它由四个州政府组成,其中一个政府就是模板与泛型了. 本条款是一个介绍性质的条款,内容不难,只需要讲清楚两个概念就行了,即什么是隐式接口,什么是编译期多态. 隐式接口是相对于函数签名所代码的显式接口而言的.当我们看到一个函数签名(即函数声明),比如说: string GetNameByStudentID(int StudentID); 我们就知道这个函数有一个整型的…
其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编译期,而const,enum定义的常量发生在编译期,两者的重要差别在于编译期里的变量是进符号表的,而预编译期的宏是简单的替换,不进符号表.因此,const, enum定义的常量具有以下优势: (1)支持类型检查 (2)支持访问权限 第(1)条优势,其实在Visual Studio编译器也已经对宏也引…
还是举书上的例子: void PrettyMenu::changeBackground(std::istream& imgSrc) { lock(&mutex); delete bgImage; ++ imageChanges; bgImage = new Image(imgSrc); unlock(&mutex); } 这段代码大致的意思就是改变背景图片,删掉旧的背景图片,记录修改次数,然后创建新的背景图片.考虑到多线程操作,所以这里用了lock和unlock. 但这里会出现问题…
举个例子: class Student { private: int ID; string name; public: string& GetName() { return name; } }; 这是一个学生的类,类里面有两个成员变量,一个是学生ID,用整数表示,另一个是姓名,用string表示.有一个公有的方法GetName(),获得学生的名字,根据条款20所说的,使用引用可以防止资源不必要地拷贝,那么在返回值这边就用string&.但现在问题来了,这个函数只是想返回学生的姓名,并不想用…
这个条款从字面意思还是很好理解的,就是在使用这个变量前才去定义,而不是很早就定义了它,而在很后面的时候才去使用.这个条款只适用于对变量声明位置没有要求的语言,比如C++.对于像C或者一些脚本语言,语法要求变量声明放在函数开始处,这个条款就不能使用了. 但其实从使用的角度而言,如果不是语法的硬性要求,还是在变量使用前再去定义变量的做法比较好.这有几点原因,最直观的就是可读性比较好,程序员在阅读代码时,看到一个陌生的变量名,不用向上翻好几页才看到它的定义类型,而且对于开发者而言,也不会出现前面定义了…
在之前的理论上调用对象的operator=是这样做的 void swap(A& x) { std::swap(a, x.a); } A& operator=(const A& a) { A temp = a; swap(temp); return *this; } 上面的代码看起来有点麻烦,但它是一个好办法. 我们可以在std里面特化我们的swap class A { private: int a; public: void swap(A& x)//防止写成friend,我…
class A { private: int a; public: A(int x) :a(x){} A operator*(const A& x) { return A(a*x.a); } }; int main() { A a(); A b = a*a;//没有问题 A b = a * ;//由于构造函数没有explicit,这里隐式转换了,也没有问题 A b = * a;//出问题了 } 老师讲过,一种是类的member函数,一种是non-member函数, 但我们为了封装性,尽量不适用f…
有下面一种情况 class A { private: int a; int b; public: A(int x, int y) :a(x), b(y){} void a_display(){ cout << a << endl; } void b_display(){ cout << b << endl; } }; 你想输出全部的时候 member函数情况 void display(){cout<<a<<b<<endl;…
1.格式统一 在调用的时候,不会去想有没有(),一律是有get(),或者set()之类的. 2.封装 能直接访问得越少,表明封装性越高, 封装性越高,我们的顾虑就少了, 例如:我们a.data*0.9的时候,不需要调用出来*0.9.只需用public的get()来调用在修改一下就好了 为什么不使用protected 在没有继承下的class下protected和private是一样的 但在发生了继承的情况下,原来只能用父类函数调用的数据,因为protected,完全暴露了出来. 而且,用了pri…