C++面向对象程序设计(第2版)第二章(类和对象的特性)知识点总结

C++面向对象程序设计

参考书目:《C++面向对象程序设计》—— 谭浩强 《C++程序设计:思想与方法》—— 翁惠玉



一、面向对象程序设计方法概述

1.面向对象的程序设计定义

       面向对象的程序设计的思路与人们日常生活中处理问题的思路相似。即,一个复杂的事物总是由许多部分组成的。当人们生产汽车时,不是先设计和制造发动机,再设计和制造底盘,然后设计和制造车身和车轮,而是分别设计和制造发动机、底盘、车身和车轮,最后把它们组装起来,这就是面向对象的基本思路。
       面向对象的程序设计要素:

  • 对象:客观世界中任何一个事物都可以看成一个对象。对象可以是自然物体,也可以是社会中的一种组织结构(班级、学校)甚至一个图形、一项计划等都可以看成对象。复杂的对象由简单的对象组成,对象是构成系统的基本单位任何一个对象都具有静态和动态的特征。 静态特征(数据)称为属性(Attribute),动态特征(函数)称为行为(Action),外界给对象发出的信息一般称作消息(Message)事件(Event)一般由多个消息组成。
  • 封装与信息隐蔽:对一个对象进行封装处理,把它的一部分属性和功能向外界屏蔽,从外面看不到这些属性和功能。封装在此有两个含义:1)把有关的数据和操作代码封装在一个对象中,形成程序中的一个基本单位,各个对象之间相互独立,互不干扰。2)把对象中的某些部分对外隐蔽,只留下与外界联系的接口接收外界的消息,这种对外界隐蔽的做法称为信息屏蔽。C++ 对象中的公有函数就是对象的对外接口。外界通过调用公有函数,访问对象中的数据成员,完成指定的操作。
  • 抽象:抽象是表示同一类事物本质的方法,它关注事物本质特征,对象是具体的,可以将一组同类对象的共同特征抽象出来,从而形成(类是对客观世界中一组相似对象的抽象和描述,是具有相同属性和行为的一组对象的集合)。即,类是对象的抽象,而对象是类的具体实例
  • 继承与重用:如果已经建立名为A 的类,现要建立一个名为 B 的类,而B 类与A 类的内容基本相同,只是在 A 类基础上增加了一些属性和行为,这样只需在 A 类的基础上添加新内容即可,这就是面向对象程序设计中的继承机制。软件重用,不仅可以利用自己过去建立的类,而且还可以利用其他人放在类库中的类建立类,这大大缩短了软件开发周期。
  • 多态性:多个相似而不完全相同的对象,收到外界给的同一个消息时,它们各自执行不同的操作,这种现象叫多态现象。在C++中所谓多态性是指:由继承而产生的新类,它的对象对同一个消息会作出不同的响应。例如,在windows中,用鼠标双击一个文件对象时,如果它是可执行文件则会执行文件中的程序,如果它是一个文本文件则会启动一个编辑器来打开这个文件,这就是面向对象程序设计中的多态性一个实际例子。

2.面向对象的程序设计特点

       面向对象与面向过程的区别:

1)面向过程的程序设计

  • 程序=数据结构+算法
  • 将客观事物中本质上密切相关、相互依赖的数据和数据的处理过程分离。面向过程的程序设计是以数据结构为基础的算法设计。
  • 这种实质上的依赖与形式上的分离使得大型程序不仅难以编写,也难以调试、修改和维护,当数据结构改变时,其相关的处理过程下需要进行全部或部分的修改,代码的重用性差。

2)面向对象的程序设计

  • 对象=数据结构+算法
    程序=(对象+对象+…+对象)+消息
  • 以对象为基础,以事件或消息来驱动对象来执行相应处理的程序设计方法。
  • 将数据及对数据的操作封装在一起,作为一个相互依存、不可分离的整体——对象。
  • 采用数据抽象和信息隐蔽技术,将这个整体抽象成一种新的数据类型——类。类的集成度越高,就越适合大型程序的开发。
  • 面向对象以数据为中心而不是以功能为中心来描述系统,因为数据相对于功能而言更具稳定性。

                                                   面向过程的程序设计方法                     VS                     面向对象的程序设计方法

在这里插入图片描述
       面向对象程序设计包括两个方面:
       ①设计所需的各种类,即决定把哪些数据和操作封装在一起。
       ②考虑怎样向对象发送消息(调用对象的成员函数),实现所需的操作。这时设计程序象一个总调度,不断地向各个对象发送消息(命令),让这些对象活动起来(激活这些对象),完成各自的职责范围工作。
注:类是C++中十分重要的概念,它是实现面向对象程序设计的基础。类是所有面向对象的语言的共同特征,所有面向对象的语言都提供了这种类型。一个有一定规模的C++程序是由许多类构成的。C++支持面向过程的程序设计,也支持基于对象和面向对象的程序设计。基于对象就是基于类,基于对象的程序是以类和对象为基础的,程序的操作是围绕对象进行的。在此基础上利用继承机制和多态性,就成为面向对象的程序设计。把一组数据和相关的操作放在一起,这就是面向对象程序设计中的对象。

3.面向对象的软件开发

  1. 面向对象分析
           面向对象分析,要按照面向对象的概念和方法,在对任务的分析中,从客观事物和事物之间的关系归纳出有关对象(对象的属性和行为)以及对象之间的联系。并将具有相同属性和行为的对象用一个类来表示。
  2. 面向对象设计
           根据面向对象分析阶段形成的需求模型,对每一部分分别进行具体的设计,首先是进行类的设计,类的设计可能包含多个层次(利用继承和派生机制)。然后以这些类为基础提出程序设计的思路和方法,包括了算法的设计。在此设计阶段,并不牵涉某一具体的计算机语言。
  3. 面向对象编程
           根据面向对象设计的结果,用一种计算机语言把它写成程序。
  4. 面向对象测试
           面向对象测试,是以类作为测试的基本单元用面向对象的方法实施测试。
  5. 面向对象维护
           任何软件产品在使用过程中,可能用户需要改进软件的性能,这就需要修改程序。由于采用了面向对象的方法,方便了维护程序。因为类的封装性,修改一个类对其他类(非子类)影响很小,极大提高了程序维护的效率。

二、类的声明和对象的定义

       在面向对象程序设计中,要使用大量的对象,要程序员对问题进行分析抽象出类的概念,在设计程序时首先要声明类类型,然后再定义类类型变量即对象。

1.类和对象的关系

       类代表了某一批对象的共性和特征。对象是类类型的一个变量。类是抽象的,不占用内存空间。对象是具体的,要占用内存空间。

2.声明类类型

       类是要用户自己定义的类型,如果程序里要用类类型,程序员必须自己根据需要声明,也可以使用别人已设计好的类。声明一个类类型与声明一个结构体类型相似。

结构体声明:
struct  student
	{
    
    
	     int    num;
	 	 char  name[20];
	 	 char  sex; 
	};
student  st1,st2;
类声明:
class  student
{
    
    
     int   num;
 	 string  name;
 	 char sex;
 	 void  setdata()
 	{
    
    	cin >> num;
 		cin >> name;
 		cin >> sex;
 	}
 	void display()
 	{
    
    	cout<< num<<endl;
 		cout<< name<<endl;
 		cout<< sex <<endl;
 	}
 };
student   st1,st2;

C++类定义的格式
在这里插入图片描述
类的访问属性有:public,private以及protected.

扫描二维码关注公众号,回复: 17063157 查看本文章
访问控制 属 性
public(公有成员) 类的外部接口,可以被本类的成员函数访问,也能在类的作用域范围内的其他函数访问。
private(私有成员) 仅允许本类成员函数访问,类外(除友元外)不能访问。
protected(保护成员) 仅允许本类成员函数及派生类成员函数访问。

注:在定义类时,这三类成员不分前后顺序,也可以重复出现。一般推荐最多出现一次。

3.定义对象的方法

  1. 先声明类类型,然后再定义对象。
    class 类名 对象名表
    class student st1, st2;
    类名 对象名表
    student st1, st2;
  2. 在声明类类型的同时定义对象。
    class 类名
    {
    private:

    public:

    } 对象名表;
  3. 不出现类名,直接定义对象(这种方法在C++中虽然是合法的,但不提倡使用。)
    class
    {
    private:

    public:

    } 对象名表;

4.类和结构体类型的区别

       用class声明的类如果不带成员访问限定符,所有成员默认限定为private;
       用struct声明的类如果不带成员访问限定符,所有成员默认限定为public。
在这里插入图片描述

三、类的成员函数

       在声明类时,必须定义访问类数据成员的函数,称之类的成员函数。

  1. 成员函数的性质
            类成员函数是函数中的一种,成员函数可以访问本类中的所有成员。一般方法是把需要与外界沟通的成员函数指定为public,作为类与外界的接口。
  2. 在类外定义成员函数
            格式:类型 类名::函数名(形参表)
                      { 成员声明 }
class  student
{
    
    
	      int   num;
	 	  string  name;
	 	  char sex;
	      public:  
			void   setdata();
	 		void  display();
};
void  student :: setdata()
	 	{
    
    	cin >> num;
	 		cin >> name;
	 		cin >> sex;
	 	}
void student :: display()
	 	{
    
    	cout<< num<<endl;
	 		cout<< name<<endl;
	 		cout<< sex <<endl;
	 	}  
student st1,st2;

注:(1)在类外定义成员函数时,必须在函数中增加类名,用于限定它属于哪个类,::是作用域限定符或称作用域运算符。上面的例子中如果函数不用成员访问限定符,函数就成了全局作用域中的display函数而不是成员函数。(2)如果在::前不带类名,或函数名前既无类名又无作用域运算符::,表示该函数是全局函数。(3)类的实现内容通常较大,为了便于阅读、管理和维护,最好将一个类拆分成一个.cpp文件和一个.h文件。

  1. 内置函数
           C++默认在类内定义的成员函数是inline函数,如果在类外定义成员函数时,系统默认不把它当作inline成员函数,此时必须在声明函数时在函数前加inline关键字。
class  student
{
    
    
    int   num;
	string  name;
	char sex;
	public:  
	inline  void   setdata()
	inline  void   display()
};
  1. 成员函数的存储方式
           用类定义对象时,系统为每个对象分配内存空间,同一类对象的成员函数是一样的如果每个对象成员函数都分配内存空间,会造成大量浪费。C++ 处理的方法是,只为对象的数据成员分配内存空间,一个类的所有对象共享一个成员函数空间。
    在这里插入图片描述

四、对象成员的引用

       定义了对象后,在程序中可以直接访问对象中的公有成员,它们可以是数据成员,也可以是成员函数。在程序中访问对象成员有三种方法:

  1. 用对象名和成员运算符访问成员
    格式:对象名.成员名
    例:st1.display(); // 调用成员函数
           display(); // 调用普通函数

注:只有成员函数可以访问类中的所有成员,而在类外只能访问公有成员。

  1. 用指向对象的指针访问成员
class Time
 {
    
    
     public:
  	 int hour;
 	 int minute;
 };
Time  t, *p; 
p= &t;
cout<< p->hour<<endl;

注·:p->hour表示p当前指向对象t中的成员hour, 此时(*p).hour也代表对象t中的成员hour,在这个例子中,p->hour、(*p).hour、t.hour三种表示是一个意思。

  1. 用对象的引用访问成员
           如果为一个对象A定义一个引用B,B是对象A的别名,A和B都是一个对象,所以完全可以通过引用访问对象中的成员。
           例:Time t1;
                  Time & t2=t1;
                  cout<< t2.hour;
           这里t2是t1的别名,所以访问t2.hour就是访问t1.hour。

注:类的成员可以是其他类的对象,但不能以类自身的对象作为本类的成员,而类自身的指针和引用可以作为类的成员。

五、类和对象的简单应用

例1:输出时间(时:分:秒)

#include <iostream>
using namespace std;
class Time
{
    
      public:
	  int hour;
	  int minute;
	  int sec;
};
//第一种
int main()
{
    
      
    Time t1;
    cin>>t1.hour >>t1.minute>>t1.sec;       
    cout<<t1.hour<<":"<<t1.minute<<":"<<t1.sec<<endl;
    Time t2;
    cin>>t2.hour>>t2.minute>>t2.sec;
    cout<<t2.hour<<":"<<t2.minute<<":"<<t2.sec<<endl;
    return 0;
}
//第二种
int main()
{
    
    
	 void set_time( Time& ) ;  //  使用引用形参
	 void show_time( Time& );
	 Time t1;
	 set_time(t1);
	 show_time(t1);
	 Time t2;
	 set_time(t2);
	 show_time(t2);
	 return 0;
} 
void set_time(Time& t)
{
    
    
	 cin>>t.hour;
	 cin>>t.minute;
	 cin>>t.sec;
}	 
void show_time(Time& t)
{
    
    
	  cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
} 
//第三种
#include <iostream>
using namespace std;
class Time
{
    
    
    public:
	   	void set_time() ;
	  	void show_time();
	private:
	   	int hour;
	   	int minute;
	   	int sec;
};
int main()
{
    
    
  	Time t1;
  	t1.set_time();
  	t1.show_time();
  	Time t2;
  	t2.set_time();
  	t2.show_time();
  	return 0;
 }
void Time::set_time()
{
    
    
	cin>>hour;
	cin>>minute;
	cin>>sec;
}	 
void Time::show_time()
{
    
    
	cout<<hour<<":"<<minute<<":"<<sec<<endl;
}

例2:在整型数组中找最大值

#include <iostream>
using namespace std;
class Array_max
{
    
    
    public:
   	void set_value();
   	void max_value();
   	void show_value();
    private:
   	int array[10];
   	int max;
};
void Array_max::set_value()
{
    
     	int i;
	for (i=0;i<10;i++)
	cin>>array[i];
}
void Array_max::max_value()
{
    
    	int i;
	max=array[0];
	for (i=1;i<10;i++)
	if(array[i]>max) max=array[i];
}
void Array_max::show_value()
{
    
    	
   cout<<"max="<<max;
}
int main()
 {
    
    	
    Array_max  arrmax;
  	arrmax.set_value();
  	arrmax.max_value();
  	arrmax.show_value();
  	return 0;
 }

在这里插入图片描述

六、类的封闭性和信息隐蔽

1.实现公用接口与私有的分离

       C++ 通过类实现封装性,类的作用就是把数据和关于操作数据的算法封装在类类型中。在声明类时,一般将数据成员指定为私有,使它们与外界隔离,把让外界调用的成员函数指定为公有,外界通过公有函数实现对数据成员的访问。外界与对象的唯一联系就是调用公有成员函数。公有成员函数是用户使用类的公用接口。用户可以调用公有成员函数实现某些功能,用户也只要了解每个公有成员函数的功能,不必了解这些功能是怎样实现的,这就是接口与实现分离。
       为了防止用户任意修改公有成员函数,从而改变对数据的操作,往往不让用户看到公有成员函数源代码。类中的数据是私有的,实现数据操作的细节对用户是隐蔽的,这种实现称为私有实现。这种类的公有接口与私有实现的分离形成了信息隐蔽。
       信息隐蔽的长处是:
       (1)如果想修改或扩充类的功能,只需修改类中有关的数据成员和成员函数,类外的部分不用修改。当接口与实现(对数据的操作)分离时,只要类的接口没有改变,对私有实现的修改不会影响程序的其他部分。
       (2)如果在编译时发现类中的数据读写有错,不必检查整个程序,只需检查本类中访问这些数据的成员函数。这就使得程序(尤其是大程序)的设计、修改和调试变得方便和简单了。

2.类声明和成员函数定义分离

       面向对象程序开发时,一般将类的声明(包括成员函数的声明)放在指定的头文件中,在程序中只要把有关的头文件包含进来即可。不必在程序中重复写类的声明。还有一种方法是把类成员函数不定义在头文件中,而另外放在一个文件中。
在这里插入图片描述
在这里插入图片描述
       在实际中,将若干个常用的功能相近的类声明集中在一起,形成类库。类库包括C++编译系统提供的标准类库,用户的类库。
类库有两个组成部分:
       (1)类声明头文件
       (2)经过编译的成员函数的定义,它是目标文件。
       用户只要把类库装入C++编译系统所在的子目录中,并在程序中用include命令把类声明的头文件包括到程序中,就能使用这些类和其中的成员函数。

猜你喜欢

转载自blog.csdn.net/weixin_43312470/article/details/108045896