目录
类和对象
类(class)
类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。
类是对现实生活中一类具有共同特征的事物的抽象。
类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。
对象组成
数据——描述对象的属性
函数——行为(操作代码),根据外界给的信息进行相应
操作的代码
具有相同的属性和行为的对象抽象为类(class)
类是对象的抽象
对象则是类的特例
对象(object)
对象是具有类类型的变量。类和对象是面向对象编程技术中的最基本的概念。
面向过程vs面向对象
面向过程程序设计
围绕功能,用一个函数实现一个功能。
程序=算法+数据结构,算法和数据结构,两者互相独立、分开设计。
面向对象程序设计
把算法和数据封装在一个对象中
面向对象程序设计的两个任务:
①设计所需的各种类和对象,即决定把哪些数据和操作封装在一起。
②考虑怎样向有关对象发送消息,以完成所需的任务。这时它如同一个总调度,不断地对各个对象发出命令,让这些对象活动起来(或者说激活这些对象),完成自己职责范围内的工作。各个对象的操作完成了,整体任务也就完成了。
参考链接:类和对象
类的声明和对象的定义
访问权限
#include <iostream>
#include <string.h>
using namespace std;
class Student //类名
{
private:
//数据成员
int num;
char name[20];
char sex;
public:
//用作输入
void set_data(int n,char *p,char s) //成员函数
{
//公有成员
num=n;
strcpy(name,p);
sex=s;
}
//用作输出
void display() //成员函数
{
cout<<"num:"<<num<<endl;
cout<<"name:"<<name<<endl;
cout<<"sex:"<<sex<<endl<<endl;
//成员函数当中操纵私有数据成员
}
};
int main()
{
Student stud1,stud2; //对象
stud1.set_data(1,"John",'f');
stud2.set_data(2,"Lisa",'m');
stud1.display(); //用对象调用成员函数
stud2.display(); //类外访问公有成员成员
return 0;
}
运行结果:
num:1
name:John
sex:f
num:2
name:Lisa
sex:m
成员访问的权限:
private(私有的)
public(公有的)
protected(受保护的)
访问权限的一般原则
数据成员:private
成员函数:public
C++中的class是C中struct的延伸
class: 访问权限默认private
struct: 访问权限默认public
建议使用 class 来定义类,而使用 struct 来定义结构体,这样做语义更加明确。
#include <iostream>
using namespace std;
struct Student{
Student(char *name, int age, float score);
void show();
char *m_name;
int m_age;
float m_score;
};
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
void Student::show(){
cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
}
int main(){
Student stu("小明", 15, 92.5f);
stu.show();
Student *pstu = new Student("李华", 16, 96);
pstu -> show();
return 0;
}
运行结果:
小明的年龄是15,成绩是92.5
李华的年龄是16,成绩是96
这段代码可以通过编译,说明 struct 默认的成员都是 public 属性的,否则不能通过对象访问成员函数。如果将 struct 关键字替换为 class,那么就会编译报错。
参考博客:c++ class和struct
定义对象的方法
命名规范
类名:首字母大写
对象名:首字母小写
先声明类类型,再定义对象
class Student //声明类类型
{
… … … …
};
…… ……
Student stud1,stud2
在声明类类型的同时定义对象
class Student //声明类类型
{
… …
} stud1,stud2;
不出现类名,直接定义对象
class //声明类类型
{
… …
} stud1,stud2;
类外定义成员函数
类内写成员函数的声明,类外进行函数的定义。
class Student
{
public:
void display(); //先在类体中作原型声明,然后在类外定义
private:
int num;.......
};
void Student::display() // ::作用域限定符或称作作用域运算符,用它声明函数属于哪个类
{
cout<<"num:"<<num<<endl;
.......
}
Student stud1,stud2;
并非所有成员函数必须公有
class Time
{
public:
void set_time();
void show_time();
private:
bool is_time(int,int,int);
int hour;
int minute;
int second;
};
bool Time::is_time(int h,int m,int s)
{
if(h<0||h>24||m<0||m>60||s<0||s>60)
return false;
return true;
}
void Time::set_time()
{
char c1,c2;
cout<<"请输入时间(格式hh:mm:ss)";
while(1)
{
cin>>hour>>c1>>minute>>c2>>second;
if(c1!=':'||c2!=':')
cout<<"格式不正确,请重新输入"<<endl;
else if(!is_time(hour,minute,second))
cout<<"时间非法,请重新输入"<<endl;
else
break;
}
}
由此可见,将只被成员函数访问的成员函数,定义为私有是正确的选择。
类的成员函数访问权限的设定
一般的做法:将需要被外界调用的成员函数指定为public,它们是类的对外接口。
并非要求把所有成员函数都指定为public:有的函数只被本类中的成员函数调用,以支持其他函数的操作,应该将它们指定为private。
私有的成员函数只能被本类中的其他成员函数所调用,而不能被类外调用。
成员函数可以访问本类中任何成员(包括私有的和公用的),可以引用在本作用域中有效的数据
成员函数存储方式
回顾结构体的存储方式:
各个域连续存储,需要的空间为各成员所需空间之和(考虑内存对齐)。
类 / 结构体类型是抽象的,在类型声明时,不涉及内存分配;
对象是具体的,在定义时,要分配内存。
分开存储数据,共用函数代码。
对于上图第二种方式,举个例子,完整程序如下:
#include <iostream>
using namespace std;
class Time
{
public:
void set_time(int,int,int);
void show_time();
private:
int hour,minute,second;
};
void Time::set_time(int h,int m,int s)
{
hour = h;
minute = m;
second = s;
}
void Time::show_time()
{
cout<<hour<<":";
cout<<minute<<":";
cout<<second<<endl;
}
int main()
{
Time t1,t2;
t1.set_time(10,47,58);
t2.set_time(12,45,26);
//用同样形式的调用,访问各自的数据成员
t1.show_time();
t2.show_time();
return 0;
}
对象成员引用的方法
私有(private)成员仅能在成员函数中引用,此时,直接使用成员名即可;
公共(public)数据成员可以在类外访问,为封装和信息隐藏,不提倡这样做;
公共(public)成员函数可以在类外访问,这是对象与外界进行消息传递的途径;
访问对象中成员的3种方法:
①通过对象名和成员运算符访问对象中的成员;
②通过指向对象的指针访问对象中的成员;
③通过对象的引用变量访问对象中的成员
通过对象名和成员运算符访问对象中的成员
访问对象中成员的一般形式
对象名.成员名
例:
t1.set_time();
若hour也为公用型,可以
t1.hour=24;
cout<<t2.hour;
注意:必须指定对象名
不能set_time()
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;
}
通过指向对象的指针访问对象中的成员
定义指向对象的指针
Time t1,*p;
p=&t1;
通过指针访问对象中的成员
p->show_time();
若hour也为公用型,
可以
p->hour=24;
cout<hour;
示例:
int main()
{
Time t1,*p;
p=&t1;
t1.set_time(12,45,15);
(*p).show_time();
p->show_time();
return 0;
}
通过对象的引用变量访问对象中的成员
引用变量共占同一段存储单元的,实际上它们是同一个对象,只是用不同的名字表示而已。(共用同一个存储空间,不另外开辟新的存储空间,例如大名、小名指代同一个人)
定义对象的引用
Time t1;
Time &t2=t1;
class Time
{
public:
void set_time( );
void show_time( );
private:
int hour;
int minute;
int sec;
};
int main( )
{
Time t1;
Time &t2=t1;
t1.set_time( );
t2.show_time( );
return 0;
}
访问私有数据成员的常用方法
通过公共函数访问私有成员
class Test
{
private:
int x, y;
public:
void setX(int a) {x=a;}
void setY(int b) {y=b;}
void printXY(void)
{cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}
};
int main()
{
Test p1,p2;
p1.setX(3);
p1.setY(5);
p1.printXY( );
}
通过公共函数访问私有成员
(惯例)利用set和get函数访问私有数据成员
class Test
{
private:
int x,y;
public:
void setX(int a) {x=a;}
void setY(int b) {y=b;}
int getX() {return x;} //返回x值
int getY() {return y;} //返回y值
};
int main()
{
Test p1,p2;
p1.setX(3);p1.setY(5);
int a,b;
a=p1.getX( ); b=p1.getY();
cout<<a<<'\t'<<b<<endl;
}