***************2018-9-18*****************
主要是构造函数的内容。
1、函数重载:
函数名相同,参数类型不同。重载函数的形参必须不同:个数不同或者是类型不同,不以参数名来作为区分,也不以返回值来区分。避免不要将通不过能的函数声明为重载函数。
重载函数为实现相同或者类似的功能。
2、C++系统函数:
C++系统库中提供了数百个函数可调用:如求平方根,绝对值等。使用系统函数须要包含相应的头文件,如cmath
3、函数的应用:斐波那契数列
4、函数重载中,可能涉及双精度数的比较,此时不能简单的使用x==y来判断是否相等或者大小。而应当使用if(abs(x-y)<1e-10)或者相似形式来表示。
*************************************************************************************************************************************************
类和对象:
1、对象:现实对象的模拟,具有属性和行为。对象是类的实例。
类:同一类对象的共同属性和行为。
定义对象时,通过构造函数初始化。删除对象时,使用析构函数释放资源。
可以使用已经有的类的对象作为新类的成员,形成类的组合。
面向对象程序设计基本特点:抽象,封装,继承,多态。
1、抽象:对同一类对象的共同属性和行为进行概括,形成类。
首先注意问题的本质及描述,其次是实现的过程和细节。
数据抽象:描述某类对象的属性或者状态(对象相互区别的物理量)
代码抽象:描述类对象的共有行为特征或具体的功能。
抽象的实现:类
举例:钟表--属性:时hour,分minute,秒second。行为:设置时间setTime()和显示时间showTime()。
2、封装:将抽象出的数据、代码封装在一起,形成类。目的是增强安全性和简化编程,使用者不必了解实现细节,而只需要通过外部接口以特定的访问权限来使用类的成员。
封装的实现是依靠类声明中的大括号{ }完成。
3、继承:在已有类的基础上进行扩展形成新的类。有利于代码的重用。
4、多态:同一名称,不同的功能实现方式。
目的:达到行为表示统一,减少程序中标识符的个数。
设计类:6个问题
1、此类型的“合法值”是什么?
2、此类型应该有什么样的函数和操作符?
3、此类型的对象该如何被创建和销毁?
4、如何进行对象的初始化和赋值?
5、对象作为函数的参数如何以值来传递?
6、谁将使用此类型的对象成员?
类的语法:
类内初始化:
公有成员(对外接口),私有成员,保护成员等概念……保护成员和私有成员的差别表现在继承和派生类的影响不同。
对象定义的语法:类名 对象名
例如:Clock myClock; 类似变量的定义:类型在前 变量名字在后,如:int b
类外的成员的访问:“对象名.成员名”,方式访问public成员。
类的成员函数:类中声明函数原型;
可以在类外给出函数体的实现,并在函数名前使用类名加以限定;(要表明函数属于哪个类)
也可以直接在类中给出函数体,形成内联函数;
允许声明重载函数和带默认参数值的函数。
内联函数inline:
举例:
5、构造函数:
类中的特殊函数,用于描述初始化算法。因为自定义的函数编译器不知道如何进行初始化,所以需要程序员自己设置构造函数让编译器知道如何初始化。
在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态。
例如,在构造Clock类时,希望设置初始值为0:0:0,就需要构造函数来设置。
构造函数的语法:
1>函数名与类名相同;
2>不能定义返回值类型,也不能有return语句;
3>可以有形式参数,也可以没有形式参数;
4>可以是内联函数;
5>可以重载;
6>可以带默认参数值。
疑问:构造函数什么时候调用?需不需要显式调用?-------------不用
构造函数的调用时机:在对象创建时被自动调用(前提是在类的定义里面声明了构造函数),例如:Clock myClock(0,0,0)
默认构造函数:
一个函数被调用时不需要实参的构造函数:参数表为空的构造函数;全部参数都有默认值的构造函数。
比如:Clock();
Clock(int newH=0,int newM=0,int newS=0);这两个默认构造函数,如果在同一个类中出现,将会产生编译错误。因为这两个函数调用时都可以不给参数
构造一个新对象时,调用构造函数是必须的,不可能说构造一个新对象不调用任何一个构造函数。
但是:为什么有时我们使用简单的程序时可以在类体中不声明构造函数呢?这是因为,定义类的时候不使用构造函数那么编译器在编译的时候会自动给我们生成一个构造函数。是一个隐含的,默认的构造函数。他的参数表是空的,不为数据成员设置初始值;如果类内定义了成员的初始值,则使用类内定义的初始值;如果没有定义类内的初始值,则以默认的方式初始化;基本类型的数据默认初始值的值是不确定的。
如变量定义时没有初始化,那么他是一个垃圾数据。如果定义的数据成员不是基本类型的数据成员,而是其他的类的对象(类组合的情况),这种情况下,对象成员的默认初始化方式有他所属的类来决定。
例子:函数名与类名相同;不能定义返回值类型;没有return语句;可以有形参;
this指的是当前对象。已经初始化好了
构造函数例题2:自己添加默认构造函数。准备多次重用的类都会提供一个默认的构造函数(编程经验)
默认构造函数是构造函数的一种重载形式。(构造函数可以重载,函数名一样,参数个数不一样)
6、委托构造函数:委托另外一个函数帮他完成初始化功能。如下:无参数的构造函数调用了有参数的构造函数,将默认的三个初始化参数传给有参数的Clock,这样就不必把同样的初始化方法再写一遍了。还可以保持代码实现的一致性,做同步修改。
7、复制构造函数:(主要的应用点在深拷贝和浅拷贝,指针部分。),有指针的时候可能默认的复制构造功能就不够用了。
就类似定义基本类型新变量时需要用一个已经存在的变量去初始化这个新变量。
复制构造函数是一种特殊的构造函数,其形参为本类对象的引用。作用是用一个已存在的对象去初始化同类型的新对象。
原因:自定义的类类型,编译器不知道如何初始化,需要自己定义。----------复制构造函数:可以规定如何用一个已经存在的对象去初始化一个新对象。可以用已知对象的引用作为构造函数的参数。
如果没有定义复制构造函数,编译器也会生成一个默认的复制构造函数。实现两个对象的数据成员之间的一一对应复制。
但有时需要自己定义如何复制:(加const是为了避免双向传递改变实参的值,我们不希望改变实参的值)
const-------既能传递参数进来,又能保证实参的安全性。
如果不希望使用默认构造函数:“=delete”