C++面向对象高级开发_极客班_第一节课笔记_section2
来源:互联网 发布:.cx域名投资 编辑:程序博客网 时间:2024/05/16 05:58
4.参数传递与返回值
参数传递与返回值是一个非常重要的内容。以前学习的时候没有体会到,这次听侯捷老师讲了之后,真的是醍醐灌顶。
4.1 构造函数的私有 与单例
calss A{public: static A& getInstance(); setup(){};private: A(){..} A(const A& other){..} int data;};A& A::getinstance(){ // 这里可以不写static static A a; return a;}
这就是一个单例。单例要求外部不可以通过调用构造函数的方式创建对象。这也是一个最基本的一个设计模式。至于其实现机制,以及static的作用,需要在之后的学习过程中具体展开。
4.2 常量成员函数const member functions
class complex{public: complex(double r=0, double i = 0) : re(r), im(i) {} double real() const { return re;} double imag() const { return im;}private: double re, im;};
所谓的常量成员函数 即:
double real() const { return re;}
其中最重要的就是 const。
类的成员函数其实就分为两种,一种是能改变数据(data),另外一种是不能改变数据的。
那么,如果设计者,在设计类的成员函数时候,就要考虑,当这个函数调用类中的数据的时候,这个函数是改变类的数据,还是没有改变,如果没有改变,那么这个成员函数,就需要加const。
这点非常重要!一定要内化。
例如:用下面代码调用上面的类
const complex A(2,1);cout<< A.real();
如果double real() const { return re;}没有const,即 double real() { return re;},此时出现的情况是,编译错误。
原因:编译器会把不加const的成员函数当成可以修改类的成员变量的函数,这这与const complex A(2.1) 的const矛盾,因此会发出编译错误。
因此,一定要养成习惯,对不改变类的成员变量的成员函数要加const!
4.3 参数传递 pass by value & pass by reference( const)
在学习C语言的时候,大学里老师讲到参数传递的时候,一般都会讲一下基本语法,然后就是会十分强调当值传递(pass by value)的时候,是复制一个值,而不是直接传值。但是并没有从更深层次区分传值与传引用的区别。
C++是讲究效率的语言。因此,如果要追求效率的角度来讲, pass by value & pass by reference( const) 就会有十分大的区别。
因为,传值,如果是大于4个字节,那么就要把这个大的数据压到函数栈里面,效率就会变慢。而C语言,就是传指针,无论什么大小,直接传地址,通过传4个字节,提高了效率。而C++是用更漂亮的传引用的方式来传递,并且引用的底册实现机制也是指针,因此C++传引用的方式,也是速度快,并且代码表现很漂亮。
所以C++编程的原则之一就是: 不管什么参数传递,能用引用的都用引用传递。或者说,参数传递首先思考的就是引用传递
这句虽然说得很绝对,但是侯捷老师,建议初学者要尽量做到内化。
再一个,当对所需要传递的参数,当不需要改变参数的内容时,要时刻记得加const。
ostream &operator << (ostream& os, const complex &x) {return os << '(' << x.real() << ',' << x.imag() << ')' <<endl;}
在这个例子中,由于要对输出流操作符 “<<”重载,因此,首先要判断参数传递是否可以用引用,然后在思考,传递的参数,在使用的过程中是否会发生改变,如果不发生改变,就要加const。
4.4 返回值传递 return by valuse & return by reference
返回值传递类型的选择也会影响C++的效率。总的原则,能进行返回值传递的尽量by reference
返回值类型的选择常常是实际编程中非常头疼的问题。
老师提供了一个思路,那就是
思考,函数最后返回的结果到底存放在哪里?这点很关键。如果是存放在已经有的空间(例如,存放在参数空间里),那就是返回引用;如果是需要另外开辟一个空间,那么,就需要传值了。
inlie complex&_doapls(complex* ths, const complex&r) { ths.re += r.re; ths.im += r.rm; return *ths;}inlien complex&_add(complex& l, complex &r) { complex temp; temp.re = l.reag() + r.reag(); temp.im = l.imag() + r.imag(); return temp;}
由于第二个例子就是 传值,因为最后是 类的加的结果,要新开辟一个空间存放,因此需要传值。
4.5 C++编程的几个非常重要的注意点
- 构造函数要用初始化列表初始化
- 数据一定要存放在private里面
- 成员函数调用成员变量,且不改变成员变量的时候要添加const
- 传递参数的时候,要尽可能使用reference,另外就是如果不改变参数要加const
- 返回值的处理,要尽量 return by reference.
4.6 friend 友元
class complex{public: complex(double r=0, double i = 0) : re(r), im(i) {} double real() const { return re;} double imag() const { return im;}private: double re, im; friend complex& _doapls(complex* ths, const complex&r);};
友元,顾名思义,就是函数可以直接调用其数据,而无需通过成员函数来调用。
友元打破了C++封装的概念,因此,友元是有危险的。从设计者的考虑,友元的使用要尽量少。当然友元会有效率上的优势,具体还有看设计者的设计思路。
4.6 相同class的各个objects互为友元
class complex{public: complex (double r = 0, double i = 0) : re (r), im (i) { } int func(const complex& param) { return param.re + param.im; }private: double re, im;};{ complex c1(2,1); complex c2; c2.func(c1);}
这个例子就生动的表明了这个结论。因为C1,C2都是相同的类的对象,因此,C2可以直接通过func调用C1的数据,因为他们互为友元。
- C++面向对象高级开发_极客班_第一节课笔记_section2
- C++面向对象高级开发_极客班_第一节课笔记
- C++面向对象高级开发_极客班_第一节课笔记_section3
- C++面向对象高级开发_极客班_第二节课笔记
- 【面向对象(高级)】_包装类笔记
- 【面向对象(高级)】_包装类笔记
- 黑马程序员_笔记五_面向对象(高级)
- 〖面向对象(高级)〗_实例分析:宠物商店笔记
- 【面向对象(高级)】_匿名内部类笔记
- 〖面向对象(高级)〗_实例分析:宠物商店笔记
- 【面向对象(高级)】_匿名内部类笔记
- Geekband_C++面向对象高级编程_第三周学习笔记
- Geekband_C++面向对象高级编程_第五周学习笔记
- Geekband_C++面向对象高级编程_第六周学习笔记
- 黑马程序员_笔记六_面向对象(高级)---抽象类
- java基础_面向对象高级特性
- java面向对象1_第五天
- IOS第三天_面向对象1
- hdoj 5194 DZY Loves Balls
- jquery 自制广告轮播小插件
- android中加载大图片到内存
- Ubuntu 12.04 安装eclipse for c++
- java 中的StringBuilder和StringBuffer
- C++面向对象高级开发_极客班_第一节课笔记_section2
- 二级指针的小应用(在主函数中获取子函数的地址)
- bash: ulimit: open files: cannot modify limit: Operation not permitted
- SQL-删除重复数据
- android 源码详解
- JSP(JavaServer Pages)
- 利用Radio Button、Check Box、Date Picker和Slider作出选择
- hdu1254 推箱子
- 内存计数器实现限频