本周类与对象的内容算是真是学完,接下来则是运用与理解。
重要内容有:
面向对象的三大特点:
封装、继承、多态
类的三种访问限定符:
1. public(公有的)2. private(私有的)
3. protected(受保护的)
特点:
1. public成员可从类外部直接访问,private/protected成员不能从类外部直接访问。
2. 每个限定符在类体中可使⽤多次,它的作⽤域是从该限定符出现开始到下⼀个限定符之前或类体结束前。
3. 类体中如果没有定义限定符,则默认为私有的,而struct如果没有定义限定符,则默认为公有的
4. 类的访问限定符体现了⾯向对象的封装性
类的六个默认成员函数:
1. 构造函数
2. 拷贝构造函数
3. 赋值操作符重载
4. 析构函数
5. 取地址操作符重载
6. const修饰的取地址操作符重载
对象
●对象是类的实例或实体。
●类与对象的关系,如同C++基本数据类型和该类型的变量之间的关系。
定义对象应注意:必须在定义了类之后,才可以定义类的对象。如:
class Point
{
public:
void InitPoint(float PointA_x, float PointA_y);
void Move(float New_x, float New_y);
float GetPointx();
float GetPointy();
private:
float P1_x,P1_y;
};
int main()
{
Point p1,p2;
}
类定义和使用时应注意:
在类的定义中不能对数据成员进行初始化。
类的任何成员都必须指定访问属性,一般将数据成员定义为私有成员或保护成员,将成员函数定义为公有成员。
类中的数据成员可以是C++语法规定的任意数据类型。
类的成员可以是其他类的对象,称为类的组合。但不能以类自身的对象作为本类的成员。
类定义必须以分号“;”结束
class与struct的不同:
class中,成员缺省情况是private。
struct中,成员缺省情况是public。
利用构造函数创建对象有以下两种方法:
(1) 利用构造函数直接创建对象.其一般形式为:
类名 对象名[(实参表)];
这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。
(2) 利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:
类名 *指针变量 = new 类名[(实参表)];
例如:
Date *date1=new Date(1998,4,28);
就创建了对象(*date1)。
复制构造函数的特点:
复制构造函数名与类名相同,并且也没有返回值类型。
复制构造函数可写在类中,也可以写在类外。
复制构造函数要求有一个类类型的引用参数。
如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。
浅复制与深复制:
关于浅复制:
●在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容
●默认复制构造函数所进行的是简单数据复制,即浅复制
关于深复制:
●通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
●自定义复制构造函数所进行的复制是浅复制。
友元函数:
如果在本类(类A)以外的其他地方定义了一个函数(函数B)
这个函数可以是不属于任何类的非成员函数,
也可以是其他类的成员函数,
在类体中用friend对其(函数B)进行声明,此函数就称为本类(类A)的友元函数。
友元函数(函数B)可以访问这个类(类A)中的私有成员
重要知识点:成员函数有两个作用:一是操作数据成员,包括访问和修改数据成员;二是用于协同不同的对象操作,称为传递消息。成员函数重点对类中数据成员操作,简单的成员函数实现可以在类中定义,此时,编译器作为内联函数处理。函数重载:函数名相同,但参数不同(类型不同,或者个数不同)的一组函数。定义对象可以带参数,对象不要在主函数以外。构造函数可以有任意类型的参数,但不能有返回类型,当定义了构造函数时,按照数据成员在类中的声明顺序进行初始化。析构函数名是在类名之前冠以一个波浪号“~”。析构函数没有参数,也没有返回值。在定义了带参数的构造函数以后,不带参数的无效,构造函数一般定义两个以上。组合对象初始化法:先初始化被包含的对象成员,再初始化本身成员。
例题:学生查询系统(不完整版):
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class student
{
string name;
int no;
int score[3];
float average;
int order;
public:
student(int id,string na,int x,int y,int z):name(na),no(id)
{
score[0]=x,score[1]=y,score[2]=z;
order=-1,average=(score[0]+score[1]+score[2])/3;
}
student()
{
score[0]=score[1]=score[2]=0;
order=-1,average=0;
}
int getNo(){return no;}
float getAverage(){return average;};
void setAverage(int avg){average=avg;}
void setOrder(int x){order=x;}
int getOrder(){return average;};
string getName(){return name;}
void setName(string name){this->name=name;}
void display();
};
void student::display()
{
cout<<name<<"\t"<<no<<"\t"<<score[0]<<"\t"<<score[1]<<"\t"<<score[2]<<"\t"<<average<<"\t\t"<<order<<endl;
}
bool cmp1(student stu1,student stu2)
{
if(stu1.getAverage()-stu2.getAverage()>=1e-9) return 1;
else return 0;
}
bool cmp2(student stu1,student stu2)
{
return stu1.getNo()<stu2.getNo();
}
class student_list
{
student list[60];
int n;
public:
student_list():n(0){};
void add();
void deleteStu();
void query();
void change();
void display(int flag);//flag=1,成绩按学号排列。flag=0,成绩按名次排列
void menu();
int search(int no);//按学号查找。找到返回在成绩表中的位置,否则返回-1
void sortList();
};
//该函数的功能是添加一个或者多个同学基本信息。
void student_list::add()
{
int no,x,y,z;
string name;
system("cls");
cout<<"请输入 学号、姓名、数学、英语、C++,输入-1结束\n";
while((cin>>no)&&no!=-1)
{
cin>>name>>x>>y>>z;
student s(no,name,x,y,z);
list[n++]=s;
sortList();
}
}
//该函数的功能是对改变了的成绩表进行名次更新。结果可以按名次排列也可按学号排列
void student_list::sortList()
{
sort(list,list+n,cmp1);
int i;
for(i=0;i<n;i++)
list[i].setOrder(i+1);
}
void student_list::display(int flag)//flag=1,按学号排列; flag=0,按名次排列
{
if(flag) sort(list,list+n,cmp2);
else sort(list,list+n,cmp1);
cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
for(int i=0;i<n;i++)
list[i].display();
}
int student_list::search(int no)
{
int i;
for(int i=0;i<n;i++)
if(list[i].getNo()==no) return i;
return -1;
}
void student_list::query()
{
int no,i;
system("cls");
cout<<"请输入要查询同学的学号,按-1结束查询:";
while(cin>>no&&no!=-1)
{
i=search(no);
if(i!=-1)
{
cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
list[i].display();
cout<<"请输入要查询的同学的学号,按-1结束查询:";
}
else cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;
}
}
//该函数的功能是实现按学号进行修改操作,并输出查找的结果
void student_list::change()
{
int no,i,x,y,z;
string name;
system("cls");
cout<<"请输入要修改同学的学号,按-1结束修改:";
while(cin>>no&&no!=-1)
{
i=search(no);
if(i!=-1)
{
cout<<"请输入修改后的姓名、数学、英语、C++\n";
cin>>name>>x>>y>>z;
student s(no,name,x,y,z);
list[i]=s;
sortList();
cout<<"请输入要修改同学的学号,按-1结束修改:";
}
else cout<<"学号输入错误,请重输,输入-1结束";
}
}
void student_list::deleteStu()
{
int no,i;
system("cls");
cout<<"请输入要删除同学的学号,按-1结束:";
while(cin>>no&&no!=-1)
{
i=search(no);
if(i!=-1)
{
for(int a=i;a<=n;a++)
{
list[a]=list[a+1];
}
sortList();
cout<<"请输入要删除同学的学号,按-1结束:";
}
else cout<<"学号输入错误,请重输,输入-1结束";
}
}
int main()
{
int a;
student s(1,"ff",66,77,88);
s.display();
cout<<s.getAverage()<<endl;
s.setName("方法");
s.display();
student_list c;
cout<<"请先添加学生信息\n";
c.add();
cout<<"请选择接下来的操作,查询输入1,修改输入2,删除输入3,按学号显示全体输入4,结束输入-1\n";
while(cin>>a&&a!=-1)
{
if(a=2) c.change();
if(a=1) c.query();
if(a=3) c.deleteStu();
if(a=4) c.display(1);
else cout<<"没有这项功能,请重新输入\n请选择接下来的操作,查询输入1,修改输入2,删除输入3,结束输入-1\n";
}
return 0;
}
本章学习心得:类与对象是c++的重点,它不易理解与运用,需要注意的细节有很多,知识点也繁多且对于我这样的初学者来说使用时不怎么方便。在编写类与对象的程序时可用“滚雪球法”,先定义一个类,再将这个类调通,增加一个功能调通一个功能,这样可以减少错误,也使编写时更具逻辑性,出现错误也可容易找出与解决。在编写程序时要有良好的条理性,明白这一行需要编写什么,怎样在之后的程序中合理使用,在做完一个项目时,我们需要不断的完善它,找出其中的不足与繁杂部分,将它优化让程序更好的运行。学完类与对象也就差不多将c++的核心部分学习完了,这部分内容需要细心研究也需要多加练习,对于现在不会或者运用不好的知识点,需要有耐心不能操之过急,在练习中逐步掌握。