文章目录
1 类和对象的概念
- 类相当于一种用户自定义的类型。
- 类的成员包括数据成员和函数成员,分别描述问题的属性和行为。
- 定义一个类之后,就可以定义该类的变量,这个变量成为类的对象(或实例),这个定义的过程也称为类的实例化。
2 类成员的访问控制
- 对类成员访问权限的控制,是通过设置成员的访问控制属性而实现的。
- 访问控制属性分为以下3种:公有类型(public)、私有类型(private)和保护类型(protected)
2.1 公有类型
公有类型成员定义了类的外部接口,在类外只能访问类的公有成员。
2.2 私有类型
私有成员只能被本类的成员函数访问,来自类外部的任何访问都是非法的。
2.3 保护类型
保护型成员的性质和私有成员的性质相似,其差别在于继承过程中对产生的新类影响不同。
3 类的定义
3.1 定义类
定义类的语法形式如下:
class 类名称
{
public:
外部接口
protected:
保护型成员
private:
私有成员
};
例如:
class Clock{
public:
void setTime(int newH,int newM,int newS);
void showTime();
private:
int hour,minute,second;
};
注意:在类中,可以只声明函数的原型,函数的实现(即函数体)可以在类外定义。
3.2 定义对象
声明一个对象和声明一个一般变量相同。
类名 对象名;
例如:
Clock myClock;
3.3 访问对象的成员
(1)访问数据成员
对象名.数据成员名
(2)调用函数成员
对象名.函数成员名(参数表)
注:在类的外部只能访问到类的公有成员;在类的成员函数中,可以访问到类的全部成员。
3.4 类的成员函数
- 函数的原型声明要卸载函数体中,原型说明了函数的参数表和返回值类型。
- 函数的具体实现是写在类定义之外的。
- 与普通函数不同,实现成员函数时要指明类的名称。
成员函数的实现:
返回值类型 类名::函数成员名(参数表)
{
函数体
}
例如:
void Clock::setTime(int newH,int newM,int newS){
hour=newH;
minute=newM;
second=newS;
}
(1)带默认形参值的成员函数
- 类成员函数的默认值,一定要写在类定义中,而不能写在类定义之外的函数实现中。
例如:
class Clock{
public:
void setTime(int newH=0,int newM=0,int newS=0);
...
};
3.5 构造函数
- 构造函数的作用就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。
- 构造函数的函数名与类名相同,而且没有返回值。
- 构造函数通常被声明为公有函数。
- 调用时无须提供参数的构造函数称为默认构造函数。
如果类中没有写构造函数,编译器会自动生成一个隐含的默认构造函数,该构造函数参数列表和函数体皆为空
class Clock{
public:
Clock() {} //编译系统生成的隐含的默认构造函数
...
};
(1)构造函数的函数原型声明:
class Clock{
public:
Clock(int newH,int newM,int newS); //构造函数的函数原型声明
...
};
(2)构造函数的实现:
Clock::Clock{int newH,int newM,int newS){
hour==newH;
minute=newM;
second=newS;
}
(3)建立对象时调用构造函数
int main(){
Clock c(0,0,0);
return 0;
}
在建立对象c时,会调用构造函数,将实参值用作初始值。
(4)初始化列表
- 与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
具体看类的组合。
3.6 复制构造函数
- 复制构造函数的作用是使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象。
- 复制构造函数的形参是本类的对象的引用。
(1) 复制构造函数的声明
class 类名
{
public:
类名(形参表);
类名(类名& 对象名);
...
};
(2)复制构造函数的实现
类名::类名(类名 &对象名)
{
函数体
}
(3)复制构造函数的调用
普通构造函数实在对象创建时被调用,而复杂构造函数在以下3中情况下都会被调用:
- 当用类的一个对象去初始化该类的另一个对象时。
- 如果函数的形参是类的对象,调用函数时进行形参和实参的结合时。
- 如果函数的返回值时类的对象,函数执行完成返回调用者时。
4 类的组合
- 类的组合描述的是一个类内嵌其他类的对象作为成员的情况,它们之间的关系是一种包含与被包含的关系。
4.1定义组合类构造函数
- 当创建类的对象时,如果这个类具有内嵌对象成员,那么各个内嵌对象将首先被自动创建。
- 在创建对象时,既要对本类的基本类型数据成员进行初始化,又要对内嵌对象成员进行初始化。
组合类构造函数定义的一般形式:
类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表),...
{类的初始化}
其中,“内嵌对象1(形参表),内嵌对象2(形参表),…”称为初始化列表,其作用是对内嵌对象进行初始化。
构造函数的调用顺序如下:
(1)调用内嵌对象的构造函数,调用顺序按照内嵌对象在组合类的定义中出现的次序(注意,不是初始化列表中的顺序)
(2)执行本类构造函数的函数体。
4.2 前向引用声明
- 在遇到复杂问题,考虑类的组合时,可能遇到两个类相互引用的情况(循环依赖),此时需要使用前向引用声明。
- 前向引用声明,是在引用未定义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。
- 尽管使用了前向引用声明,但在提供一个完整的类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。
注意:当使用前向引用声明时,只能使用被声明的符号,而不能涉及类的任何细节。