最后一次更新于 2021-11-21 at 14:47: 49 CST
第二次更新于2021-11-21 at 11:26:23 CST
第一次更新于 2021-11-18 at 22:10:23 CST
1 绪论
-
什么是面向对象的方法?
首先,它将数据及对数据的操作方法放在一起,作为一个互相依存、不可分离的整体——对象。
对同类型对象抽象出其共性,形成类。
类中的大多数数据,只能通过本类的方法进行处理。
类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信
-
面向对象的基本概念
-
对象
面向对象方法中的对象,是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。
对象由一组属性和一组行为构成
-
类
面向对象中的“类”,是具有相同属性和服务的一组对象的集合。
-
封装
封装是面向对象的一个重要原则,就是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐藏对象的内部细节。
-
继承
特殊的类的对象拥有其一般类的全部属性和服务,称作特殊类的对一般类的继承。
-
多态性
多态性是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。
-
-
C++两个主要特点——[ 尽量兼容C,支持面向对象的方法 ]
-
面向对象程序设计的基本特点
-
抽象
面向对象方法中的抽象,是指对具体问题(对象)进行概括,抽出一类的对象的公共性质并加以描述的过程
-
封装
封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的函数代码进行有机的结合,形成“类”,其中的数据和函数都是类的成员。
-
继承
C++中提供了类的继承机制,允许程序员在保持原有类特性的基础上,进行更具体、更详细的说明。
-
多态
多态是指一段程序能够处理多种类型对象的能力。在C++语言中,这种多态性可以通过强制多态、重载多态、类型参数化多态、包含多态4种形式来实现。
-
-
对象和类的联系
类是对象的抽象;对象是类的一个特定实例。
2 参数传递
-
值传递不影响实参,引用传递和指针传递可以影响实参
-
值(val)传递
#include <iostream> using namespace std; /*val*/ void swap(int i,int j){ int temp; temp = i; i = j; j = temp; cout<<"swap in the function: "<< "i="<<i<<" j="<<j<<endl; } int main(){ int a,b; a = 1; b = 2; swap(a,b); cout<<"out the function: "<< "a="<<a<<" b="<<b<<endl; } /* * swap in the function: i=2 j=1 * out the function: a=1 b=2 */
-
引用(reference)传递
#include <iostream> using namespace std; /*reference*/ void swap(int &i,int &j){ int temp; temp = i; i = j; j = temp; cout<<"swap in the function: "<< "i="<<i<<" j="<<j<<endl; } int main(){ int a,b; a = 1; b = 2; swap(a,b); cout<<"out the function: "<< "a="<<a<<" b="<<b<<endl; } /* * swap in the function: i=2 j=1 * out the function: a=2 b=1 * */
-
指针(pointer)传递
#include <iostream> using namespace std; /*pointer*/ void swap(int *i,int *j){ int temp; temp = *i; *i = *j; *j = temp; cout<<"swap in the function: "<< "i="<<*i<<" j="<<*j<<endl; } int main(){ int a,b; a = 1; b = 2; swap(&a,&b); cout<<"out the function: "<< "a="<<a<<" b="<<b<<endl; } /* * swap in the function: i=2 j=1 * out the function: a=2 b=1 * */
3 内联函数
-
为什么使用内联函数
内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。
如此,节省了参数传递、控制转移等开销。
-
使用内联函数的条件
通常内联函数应该是比较简单的函数,结构简单,语句少。如果将一个复杂的函数定义为内联函数,反而会造成代码膨胀,增大开销。
-
将一个函数声明为内联函数——使用关键字
inline
inline [returnType] [functionName](args){ [function body]; }
-
实例——根据圆的半径求其面积
#include <iostream> using namespace std; const double PI = 3.1415926; inline double getArea(double radius){ return PI*radius*radius; } int main(){ double radius = 2.5; double area = getArea(radius); cout<<area<<endl; return 0; }
4 带默认形参值的函数
-
**函数在定义时可以预先声明默认的形参值。**调用时如果给出实参,则用实参来初始化形参,如果没有给出实参,则采用预先生命的默认形参值。例如
#include <iostream> using namespace std; inline double getGravity (double weight,double gravition_acceleration=9.80665); int main(){ double m0 = 10.0; cout<<"m0="<<m0<<endl; cout<<"gravition_acceleration=9.80665 -> "<<getGravity(10.0)<<endl; cout<<"gravition_acceleration=10.0000 -> "<<getGravity(10.0,10.0)<<endl; } inline double getGravity (double weight,double gravition_acceleration) { return weight*gravition_acceleration; } /* * m0=10 * gravition_acceleration=9.80665 -> 98.0665 * gravition_acceleration=10.0000 -> 100 * */
-
两个注意事项
-
在相同的作用域内,不允许在同一个函数的多个声明中对同一个参数的默认值重复定义,即使前后定义的值相同也不行。
-
反过来,若作用域不同,前后定义的默认值不同是允许的。
例子,在类内和类外定义带默认参数的函数
#include <iostream> using namespace std; inline int fun(int i=0){ return i; } class Samp1e { public: inline int fun(int j=1){ return j; } private: int var; }; Samp1e s; int main(){ cout<<"member function return: "<<s.fun()<<endl; cout<<"function out of the class return: "<<fun()<<endl; } /* * member function return: 1 * function out of the class return: 0 * */
-
5 函数的重载
-
概念
两个以上的函数,具有相同的函数名,但是形参的个数或者类型不同,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用哪一个函数,这就是函数的重载。
-
例子:
#include <iostream> using namespace std; int additionOfSquare(int i,int j){ cout<<"int"<<endl; return i*i+j*j; } double additionOfSquare(double i,double j){ cout<<"double"<<endl; return i*i+j*j; } int main(){ double r = 2.71828, s = 3.1415926; cout<<additionOfSquare(r,s)<<endl; int u = (int) r,v = (int) s; cout<<additionOfSquare(u,v)<<endl; } /* * double * 17.2587 * int * 13 */
-
注意
当使用带有默认形参值的函数重载形式时,需要注意防止二义性。例如下面的两个函数原型,在编译时无法区别为不同的重载形式。
void fun(int length,int width=2,int height = 3); void fun(int length);
再如
int additionOfSquare(int i,int j){ cout<<"int"<<endl; return i*i+j*j; } double additionOfSquare(double i,double j){ cout<<"double"<<endl; return i*i+j*j; }
调用
int main(){ double r = 2.71828; int u = (int) r; additionOfSquare(r,u); }
也会产生歧义。
6 类和对象
-
序言
-
类是面向对象程序设计方法的核心,利用类可以实现对数据的封装和隐蔽
-
在面向对象程序设计中,程序模块是由类构成的。类是对逻辑上相关的函数与数据的封装,它是对问题的抽象描述。
-
-
类的定义
class [className]{ public: [external interface]; protected: [protected members]; private: [private members]; };
-
类成员的访问控制
派生对象 | 外部 | 友元 | |
---|---|---|---|
public | √ | √ | √ |
private | X | X | √ |
protected | √ | X | √ |
-
对象
略;
-
成员函数
-
成员函数的定义
returnType className::functionName(args...){ function body; }
在类内定义成员函数时,可以不指明该函数属于哪个类
returnType functionName(args.){ function body; }
-
成员函数的调用
class A
-