目录
C++类和对象的基础
综述
C++类和对象的基础:面向对象、类的声明和对象的定义、类的构建、类外访问对象成员的方法、类和对象的简单应用、类的封装性(头文件中""和<>的区别)。
带举例,供学习、参考和查阅。
面向对象
对象(object):自然物体、逻辑结构等。
对象=属性(静态特性)+行为(动态特性)。
如:班级=属性(班主任、学生数量……)+行为(上课)。
C++对象=数据(属性)+函数(行为)。
对象封装(encapsulation):把对象不对外展示的属性和功能隐藏。
抽象:将具有相同特性的事物归纳、集中成一个同一类型。
如:将一批具体数据抽象出数据类型。
类和对象的关系:对象抽象出类,对象的类型是类,类的具体化是对象。
继承:本质是代码复用, 在基类中提供统一的虚函数接口,让派生类进行重写,就可以使用多态。
多态:由继承而产生的相关不同的类,其对象对同一消息作不同响应。
面向对象程序设计核心:程序设计以类和对象为核心。
面向对象程序设计特点:抽象性、封装性、继承性、多态性。
C++支持:面向过程程序设计、基于对象程序设计(以类和对象为基础,程序操作围绕对象进行)、面向对象程序设计(基于对象基础上,利用继承机制和多态性,或者说在有类和对象的基础上有继承机制和多态性,才是面向对象)。
面向对象的软件开发:面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程(OOP)、面向对象测试(OOT)、面向对象维护(OOSM)。
面向对象程序设计中相关名词:对象、方法、消息,例:
对象:stud
方法:display()
消息:stud.display()
类的声明和对象的定义
类的声明:描述类的结构和接口,没有分配内存和初始化。
对象的定义:创建对象,分配内存并初始化。
C++中类的声明与C中结构体的声明一样,只是关键字从struct换成class。
为了兼容C,C++中类的声明也可以使用struct,即C++中类的声明使用class和struct都可以。
使用class与struct进行类的声明时,当未指定访问类型时,会使用默认类型,二者的默认类型不同:
struct:默认类型 public
class:默认类型 private
类的声明格式:类头+类体,类体结束需要加分号,如下例:
class{
private:
//私有数据成员和私有成员函数
public:
//公有数据成员和公有成员函数
};//末尾记得加上“分号”
类的声明,如下例:
class Student{
private:
int num;string name;char sex;
public:
void display()
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"sex:"<<sex<<endl;
}
};
声明了类以后,就可以定义该类的若干对象,如下例:
student s1,s2,s3;
类的构建
类的成员函数:类的成员函数也叫类函数,用法和一般函数基本一致,但区别在于它只是属于一个类的成员,出现在类体中。
类成员:公有成员(public):可以类外调用;私有成员(private):只能类内调用;保护成员(protected):类内调用、派生类调用。
域限定符"::":域限定符前没有类名【::display()】或函数名前没有类名也没有域限定符【display()】,则该函数不属于任何类,为全局函数,即普通函数。
除了类内定义成原函数,很多情况都是类外定义成原函数,需要用“类名::函数名”指定,如下例:
class Student{
private:
int num;string name;char sex;
public:
void display();//公有成员函数原型声明
};
void Student::display()//在类外定义display类函数
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"sex:"<<sex<<endl;
}Student stud1,stud2;//声明两个对象
incline成员函数:类的成员函数也可以指定为内联函数,只要函数代码较少且被频繁使用(在成员函数类型名前加上incline即可),提高执行效率。
成员函数的存储方式:同一类定义多个对象时,每个对象的数据成员各自占据独立空间,共享同个函数代码段,不占用对象存储空间。
不同对象使用同个函数代码段时,使用this指针指向不同对象。
类外访问对象成员的方法
1.使用对象名+成员运算符(成员必须定义成公用成员):
对象名.成员名
stud1.num=1001;
2.指向对象的指针:
Time t,*p;
p=&t;
cout<<p->hour;//p指向对象t中的hour成员
3.对象的引用:
Time t1;
Time &t2=t1;
cout<<t2.hour;//t2.hour等价于t1.hour
类和对象的简单应用
类外访问对象成员(类外引用对象成员),实例1:
#include <iostream>
using namespace std;
class Time{
public:
int hour;int minute;int second;
};
int main()
{
Time t1;//声明Time类的对象t1
Time &t2=t1;//t2是t1的引用
cin>>t2.hour>>t2.minute>>t1.second;
//用t2访问和用t1本身访问没有任何区别
cout<<t1.hour<<":"<<t1.minute<<":"<<t2.second<<endl;
}
类外访问对象成员(类外声明对象),实例2:
#include <iostream>
using namespace std;
class Time{
public:
int hour;int minute;int second;
};
int main()
{
Time t1;//声明Time类的对象t1
Time t2;//声明Time类的对象t2
cin>>t1.hour>>t1.minute>>t1.second;
cin>>t2.hour>>t2.minute>>t2.second;
cout<<t1.hour<<":"<<t1.minute<<":"<<t1.second<<endl;
cout<<t2.hour<<":"<<t2.minute<<":"<<t2.second<<endl;
}
使用函数输入输出,实例3:
#include <iostream>
using namespace std;
class Time{
public:
int hour;int minute;int second;
};
int main()
{
void set_time(Time&);//set_time要访问对象成员,所以形参是对象的引用,即Time&,不需要返回数据,返回类型void
void show_time(Time&);//调用输出函数
return 0;
}
void set_time(Time& t)//输入函数
{
cin>>t.hour>>t.minute>>t.second;
}
void show_time(Time& t)//输出函数
{
cout<<t.hour<<":"<<t.minute<<":"<<t.second<<endl;
}
使用有默认参数的函数输入输出(输出函数没法带默认参数,输出该是多少就是多少),实例4:
#include <iostream>
using namespace std;
class Time{
public:
int hour;int minute;int second;
};
int main()
{
Time t1;//声明Time类的对象t1
set_time(t1,12,23,34);//调用输入函数
show_time(t1);//调用输出函数
Time t2;
set_time(t2);
show_time(t2);
return 0;
}//运行结果:12:32:43 0:0:0
void set_time(Time& t,int hour=0,int minute=0,int second=0)//输入函数
{
t.hour=hour;
t.minute=minute;
t.second=second;
}
void show_time(Time& t)//输出函数
{
cout<<t.hour<<":"<<t.minute<<":"<<t.second<<endl;
}
使用成员函数输入输出(在程序设计中最好使用这种方式进行输入输出,把数据成员和成员函数放在一起,用成员函数来调用数据成员),最重要的就是这种实现方式,实例5:
#include <iostream>
using namespace std;
class Time{
public://定义两个输入输出的公有函数
void set_time();
void show_time();
private://私有,在类外不能访问,要访问只能通过公有函数
int hour;int minute;int second;
};
int main()
{
Time t1;//声明Time类的对象t1
t1.set_time();
t1.show_time();
Time t2;//声明Time类的对象t2
t2.set_time();
t2.show_time();
return 0;
}//运行结果:12:32:43 0:0:0
void Time::set_time()//类外定义成员函数要加::
{
cin>>hour>>minute>>second;
}
void Time::show_time()//输出函数
{
cout<<t.hour<<":"<<t.minute<<":"<<t.second<<endl;
}
类的封装性(头文件中""和<>的区别)
类的封装:将类的数据成员和成员函数集成到一个类中。
数据成员:一般声明为私有,内部实现。
成员函数:一般声明为公有,外部接口(除非某些成员函数不想被外界调用)。
外界:通过类的公有函数,间接进行对私有成员的操作(外界是与类的私有成员的唯一联系渠道,就是该类的公有成员函数)。
类的声明和类的成员函数定义的分离:类的声明→.h文件,类的成员函数定义→.cpp文件,例:
#include <iostream>//在student.cpp进行类的成员函数定义
using namespace std;
#include "student.h"//此行不能漏写
void Student::display()//类外定义display函数
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"sex:"<<sex<<endl;
}
#include <string>//保存在student.h中
using namespace std;
class Student{
public:
display();//公有成员函数声明
private:
};
#include <iostream>//保存在main.cpp中
#include <student.h>
int main()
{
Student stud;
stud.display();
return 0;
}
//文件构成一个project
类库:将若干功能相近的类声明集中在一起,形成类库。
类库的构成:类声明头文件、经过编译的头文件函数定义的目标文件。
类库的使用:在程序中用#include命令将有关类声明的头文件包含到程序中。
头文件的引用: C++中头文件的引用时有""和<>两种,若是使用错误,可能会导致编译不通过,出现错误:“error C1083: 无法打开包括文件:“rapidxml.hpp”: No such file or directory ”,为了避免此类错误,下面进行分析两者区别:头文件的引用时,使用""是搜索所有目录,使用 <> 是搜索当前目录。
正常情况下,自行定义的头文件应使用"",使用<>会报错找不到头文件,因为自行定义的头文件存放在工程目录(也就是编译器的当前目录)下,而不是存放在公共头文件目录下;系统提供的头文件,如库函数的头文件,应使用<>。