题头的话:长按点赞可私我赠送50+本C与C++书籍电子书资源
啥叫类和对象?不学后悔一辈子!
学了浪费十分钟嘻嘻嘻
咱都知道,C++它是面向对象的。
而类class的任务就是创建对象。
“类”是一种数据类型,而“对象”是“类”的实例或者说变量。变量名张三即使某个学生类中的某个具体对象的标识。类和对象的关系相当于普通数据类型与其变量的关系。创造了一个类只是创造了一种新的数据类型,再在此基础上创造一个变量(对象)才是真正的创立了这种数据类型的实体。例如:
类 空格 学生类{ //此处创立学生类,相当于创立了int类型。
私人的:
//私有de数据成员和成员函数
//C++类的核心竞争力在于它的“封装”特性
//这里的值受到保护,外界不能访问。所以相当于把它“封装”了起来。
//这里是这个“类”的细致刻画。比如:
string 名字; //设置学生类的姓名
int 学号; //设置学生类的学号
//类定义的数据成员不能初始化.即:string 名字=张三;
//姓名“名字”和学号“学号”反应了“学生类”的特征
//这里既然保护了这些数据,那么肯定也要有办法修改这些数据。
//那就是下面的“接口”public
公共的:
//公有de数据成员和成员函数。一般都是函数
//“接口”是个很形象的比喻。可以这样理解:
无返回值 空格 给名字赋值(string 形式参数){ //这就是一个名叫“给名字赋值”的函数,承担起联系“类”的内外的任务。
//联系内外,把外界实际参数的“张三”先通过函数赋值给形式函数.
名字 = 形式参数; //形式函数“张三”把值“张三”赋值给受保护的“名字”
//外界能访问这个名叫“给名字赋值”的函数,因为它处在“ 公共的: ”这一部分
//但是外界不能访问这个私有的数据“名字”,因为它处在“ 私有的: ”这一部分
//类内可以相互访问和修改,这是一个名叫“给名字赋值”的处于“ 公共的: ”这一部分的类内函数。外界可以访问,于是它承担起联系“类”的内外的任务,用它来修改这个私有的数据“名字”。
}
无返回值 空格 给学号赋值(int 形式参数){ //这就是一个名叫“给学号赋值”的函数,承担起联系“类”的内外的任务。
//联系内外,把外界实际参数的“2021XXXX”的八位学号先通过函数赋值给形式函数.
学号 = 形式参数; //形式函数“2021XXXX”的八位学号把值“2021XXXX”的八位学号赋值给受保护的“学号”
//外界能访问这个名叫“给学号赋值”的函数,因为它处在“ 公共的: ”这一部分
//但是外界不能访问这个私有的数据“学号”,因为它处在“ 私有的: ”这一部分
//类内可以相互访问和修改,这是这一个名叫“给学号赋值”的处于“ 公共的: ”这一部分的类内函数。外界可以访问,于是它承担起联系“类”的内外的任务,用它来修改这个私有的数据“学号”。
}
无返回值 空格 打印名字(无参数){
输出<<"我的名字是:"<<名字<<回车; //这就是一个名叫“打印名字”的无参函数,功能和名字一样
//类内可以相互访问和修改,这是这一个名叫“打印名字”的处于“ 公共的: ”这一部分的类内函数。外界可以访问,于是它承担起联系“类”的内外的任务,用它来打印这个私有的数据“名字”。
}
无返回值 空格 打印学号(无参数){
输出<<"我的学号是:"<<学号<<回车; //这就是一个名叫“打印学号”的无参函数,功能和名字一样
//类内可以相互访问和修改,这是这一个名叫“打印学号”的处于“ 公共的: ”这一部分的类内函数。外界可以访问,于是它承担起联系“类”的内外的任务,用它来打印这个私有的数据“学号”。
}
protected:
//受保护de数据成员和成员函数
//暂时用不上,之后咱学习了友元再说。
};//类结束时分号不要漏了!!
int main{
//然后开始创建一个学生“张三”的对象
学生类 空格 学生壹; //就好像: int x,y; 一样自然
学生壹.给名字赋值(string 张三); //就好像:x=10086; 一样自然
学生壹.给学号赋值(int 2021XXXX); //就好像:y=1008611;一样自然
学生壹.打印名字(); // printf("我的名字是:",x);
学生壹.打印学号(); // printf("我的学号是:",y);
//然后开始创建一个学生“zhangsan”的对象
学生类 空格 学生贰; //就好像: int a,b; 一样自然
学生贰.给名字赋值(string zhangsan); //就好像:a=zhangsan; 一样自然
学生贰.给学号赋值(int 2021XXXY); //就好像:b=2021XXXY;一样自然
学生贰.打印名字(); // printf("我的名字是:",a);
学生贰.打印学号(); // printf("我的学号是:",b);
//由此也可以看出,为什么类定义的数据成员不能初始化。总不能你初始化一个张三,然后所有人都叫“张三”吧
return 0;
}
//结束
类的定义
类由三部分组成:类名,数据成员和成员函数,类定义的一般格式如下:
class 类的名字
{
private:
//私有de数据成员和成员函数
public:
//公有de数据成员和成员函数
protected:
//受保护de数据成员和成员函数
};
例:设计一个学生类,可以打印学生的姓名学号
#include<iostream>
using namespace std;
#include<string>
class Student{
//访问权限
//公共权限
public:
void studentname(string s)
{
m_name=s;
}
void studentID(int ID)
{
m_ID=ID;
}
void showStudent()
{
cout<<"我的名字是:"<<m_name<<endl;
cout<<"我的学号是:"<<m_ID<<endl<<endl;
}
//私有权限
private:
string m_name;
int m_ID;
};
int main()
{
//创建一个具体学生,实例化对象
Student studentOne;
//给对象stdentOne通过公共接口进行属性赋值操作
studentOne.studentname("zhangsan");
studentOne.studentID(20212021);
//显示学生信息
studentOne.showStudent();
//创建另一个具体学生,实例化对象
Student studentTwo;
//给对象stdentTwo通过公共接口进行属性赋值操作
studentTwo.studentname("BC");
studentTwo.studentID(20212022);
//显示学生信息
studentTwo.showStudent();
return 0;
}
共有的(public)这一部分在类外部就可以通过类的对象进行访问。
- 通过对象调用成员
格式:
对象名.公有成员
其中,“.”称为对象选择符,简称点运算符。
(以上就是采用的点运算符) - 通过指向对象的指针调用成员
格式:
指向对象的指针->成员
或
(*对象指针名).公有成员 - 通过对象的引用调用成员
格式:
对象的引用.成员
需要注意,只有共有的(public)这一部分在类外部可以通过类的对象进行访问,而私有的(private)不能。
如定义时钟类:
class Mycolock
{
private:
int hour,minute,second;
public:
void init();
void update();
void display();
};
Myclock colock; //定义对象clock
Myclock *pcolock; //定义指向Myclock类对象的指针pclock
clock.init(); //通过对象访问公有成员函数
pclock=&clock; //指针pclock指向clock
pclock->display(); //通过指针访问成员函数
clock.hour=4; //错误,因为对象不能访问其私有成员
例:设计一个球类,求球的表面积:
#include<iostream>
using namespace std;
const double PI =3.14;
class Sphere{
//访问权限
//公共权限
public:
//行为
void sphereR(int R)
{
m_r=R;
}
void showSphere()
{
cout<<"球的表面积是:"<<4*PI*m_r*m_r<<endl;
}
private:
//属性
//半径
int m_r;
};
int main()
{
int r;
cin>>r;
Sphere SOne;
SOne.sphereR(r);
SOne.showSphere();
return 0;
}
- class是定义类的关键字,类名是一种标识符,必须符合C++标识符命名规则,花括号内是类的定义体部分,说明该类的成员。类的成员包括数据成员和成员函数。
- 类成员有三种访问控制权限,分别是private(私有成员),public(公有成员)和protected(受保护成员)。在每一种权限下,均可以定义数据成员和成员函数。
- private(私有成员)只能由本类的成员函数或者其他某些特殊说明的函数(如友元函数)访问。该关键字在第一部分时可以默认省略。
- public(公有成员)公有成员对外完全开放,提供接口功能。用户通过公有成员访问该类中的数据。
- protected(受保护成员)只能由本类的成员函数或者其他某些特殊说明的函数(如友元函数,共有派生成员)访问。protected(受保护成员)和private(私有成员)在一般情况下含义相同,它们的区别主要体现在“继承”中对其影响不同。
- 缺省访问控制(未指定private,public和protected)系统认为是私有private成员。
- 类具有封装性,C++通过类进行数据封装。
- 一般情况下,类的名字的第一个字母大写,以区别普通的变量和对象。
- 由于类中的公共成员提供了一个类的接口。所以在一般情况下,先定义公有成员,,这样在阅读时首先了解这个类的接口。当然,如果你愿意,你可以以任意次序书写三者。
- 成员数据可以是任意数据类型,但是不能是自动(auto),寄存器(register)或外部(extern)进行说明。
- 注意在定义类的时候,不允许初始化数据,下面定义是错的:
class student{
private:
string name=zhangsan;
int ID=20212021;
···
};
-
类和结构体区别
类 默认私有
结构体 默认公开 -
不要丢掉类结束时的分号。
类中成员函数的定义
成员函数————对封装的数据进行操作的唯一方法!
类中成员函数的定义方法有两种:外联定义和内联定义。
外联成员函数
外联成员函数是指在类定义体内(位置1)声明(做法1)成员函数
外联成员函数——在类定义体外(位置2)定义(做法2)成员函数
下面是细节:
- 在类中声明函数时,他所带的函数参数可以只指出其类型,而省略形式参数名。
- 在类外定义函数时,必须在函数名前缀上类名,在函数名和类名之间加上作用域区分符::,作用域区分符::指明一个函数或数据成员所在的类。(作用域区分符::前若不加类名,则成为全局函数或全局数据)
类外定义成员函数的具体形式如下:
返回值类型 类名::成员函数名(形式参数表)
{
//函数体
}
举个栗子
定义日期类:
哈哈哈这个是C与C++混合编制。其中关于计算星期几时使用的C语言编程,其余部分为C++
#include<stdio.h>
#include<iostream>
using namespace std;
#include<string>
//外联定义
class Tdate //定义日期类
{ //在类中声明函数
public: //定义公有成员函数
void set(int y,int m,int d); //置日期值
string isLeapYear(); //判断是否闰年
void print(); //输出日期值
int week(); //输出今天周几
~Tdate()
{
cout<<endl<<"over"<<endl; //这是一个析构函数,以后会讲
}
private: //定义私有数据成员
int month; //这些数据受到保护
int day; //封装的数据进行操作的唯一方法
int year; //就是成员函数
}; //类定义体的结束
//在类外定义函数
void Tdate::set(int y,int m,int d) //设置日期值
{ //通过形式参数传给受保护的数据
month=m;
day=d;
year=y;
}
string Tdate::isLeapYear() //判断是否是闰年
{
int yes=(year%4==0&&year%100!=0)||(year%400==0);
if(yes)return "YES";
return "NO";
}
void Tdate::print() //输出日期值
{
cout<<month<<"/"<<day<<"/"<<year;
}
int Tdate::week() //输出今天周几
{
Tdate::print();
cout<<"的话,应该是";
int i,x=0;
int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};
for(i=1980;i<year;i++)
if((i%4==0&&i%100!=0)||i%400==0)
x=x+2;
else x++;
if((year%4==0&&year%100!=0)||year%400==0)
a[1]=29;
for(i=1;i<month;i++)
x+=a[i];
x=(x+day)%7;
switch(x)
{
case 0:printf("Monday");break;
case 1:printf("Tuesday");break;
case 2:printf("Wednesday");break;
case 3:printf("Thursday");break;
case 4:printf("Friday");break;
case 5:printf("Saturday");break;
case 6:printf("Sunday");break;
}
return 0;
}
int main()
{
Tdate today;
today.set(2021,7,14);
today.print();
cout<<endl;
cout<<endl;
cout<<"今年是闰年吗?"<<endl<<today.isLeapYear()<<endl;
cout<<endl;
cout<<endl;
cout<<"今天是周几呢?"<<endl;
today.week();
return 0;
}
其输出结果为:
7/14/2021
今年是闰年吗?
NO
今天是周几呢?
7/14/2021的话,应该是Wednesday
over
内联成员函数
又称:内联函数,内部函数,内置函数
两种定义方法:
- 类定义体内定义(隐式声明)
class Tdate //定义日期类
{ //在类中声明函数
public: //定义公有成员函数
void set(int y,int m,int d) //置日期值
{ //通过形式参数传给受保护的数据
month=m;
day=d;
year=y;
}
string isLeapYear() //判断是否闰年
{
int yes=(year%4==0&&year%100!=0)||(year%400==0);
if(yes)return "YES";
return "NO";
}
void print() //输出日期值
{
cout<<month<<"/"<<day<<"/"<<year;
}
~Tdate()
{
cout<<endl<<"over"<<endl; //这是一个析构函数,以后会讲
}
private: //定义私有数据成员
int month; //这些数据受到保护
int day; //封装的数据进行操作的唯一方法
int year; //就是成员函数
};
- 使用online关键字()
如果定义在类定义体外的函数使用关键字inline,则可以将定义在类定义体外的函数声明为内联定义函数,这时可在类定义体内相应函数的前面增加关键字online,将该函数声明为内联成员函数。例如,Tdate类中Set()内联函数的定义体为:
inline void Tdate::Set(int m,int d,int y) //设置日期值
{
month=m;
day=d;
year=y;
}
或
void inline Tdate::Set(int m,int d,int y) //设置日期值
{
month=m;
day=d;
year=y;
}