首先我个人认为类是非常难的一个知识点,并且是一个非常重
要的知识点。我认为自己在这章掌握并不是很成功,为此我会花
更多时间去学习这方面知识,下面是我对这章知识的认识:
第一点类的定义:
类是对具有相同属性和行为的一组对象的抽象与统一描述。是用户自定义的数据类型
类的定义包括行为和属性两个部分。
属性以数据表示,行为通过函数实现
格式:类的最后一定加“;”
各成员函数的实现
- <span style="font-family:SimSun;">class 类名
- {
- public:
- 公有数据成员和成员函数;
- protected:
- 保护数据成员和成员函数; 类成员可以是数据类型,也可以是函数;
- private:
- 私有数据成员和成员函数;
- };</span>
由于隐藏数据是opp主要目标之一,数据项通常放在私有部分,组成类接口的成员函数放在公有部分;
不必要在类声明中使用关键字privat,因为这是类对象的默认访问控制;
public与private之间唯一的区别是,结构的默认访问类型是public,而类为prite;
实现类成员函数:
- <span style="font-family:SimSun;">返回值类型 类名::成员函数名(参数表)
- {
- 函数体
- } </span>
访问类成员
- <span style="font-family:SimSun;">对象成员的访问包括:
- ●圆点访问形式:对象名.公有成员
- ●指针访问形式</span>
对象指针变量名->公有成员
*注意事项
1.类的成员可以是其他人的对象,但不能以类自身的对象作为本类的成员,而类自身的指针和引用可以作为类的成员。
2.类定义必须以分号“;”结束。
3.类与结构体的区别:没有明确指定类成员的访问权限时,C++结构体的成员是公有的,而类的成员是私有的。
类的构造函数和析构函数
为对象分配空间;对数据成员赋初值;请求其他资源
c++提供了一个特殊的成员函数--类构造函数,专门用于构造新对象,将值赋给他们的数据成员
构造函数没有返回值,实际上构造函数没有声明类型;
构造函数的参数标识的不是类成员,而是赋给类成员的值,因此,参数名不能与类成员相同;
当一个对象作用域结束时,系统自动调用析构函数
析构函数的作用是进行对象消亡时的清理工作
c++提供了两种使用构造函数来初始化对象的方式:
第一种方式:显示地调用析构函数 例如:stock food=stock(“world cabbage”,250,1.25);
第二种方式:隐式地调用析构函数 例如:stock garment(”furry mason“,50,2.5);
默认构造函数:
默认构造函数是在未提供显式初始值时,用来创建对象的构造函数。
格式:
- <span style="font-family:SimSun;">格式:
- funname(参数列表):初始化列表
- { 函数体,可以是空函数体 }
- 初始化列表的形式:
- 成员名1(形参名1),成员名2(形参名2),成员名n(形参名n)
- </span>
对象生存期结束时,需要做清理工作,比如:释放成员(指针)所占有的存储空间
析构函数可以完成上述工作。
析构函数自动调用(隐式调用)
析构函数没有返回值,不能有参数,也不能重载
- <span style="font-family:SimSun;">类名::~类名()
- {
- 函数语句
- }</span>
参数个数相同 参数类型不同
定义成员函数时,使用作用域解析运算符(::)来标示函数所属的类;
类方法可以访问类的private组件;
例如:void stock::update(double price)
类方法的完整名称中包括类名。
其定义位于类声明中的函数都将自动成为内联函数;
内联函数:
内联函数作用:减少频繁调用小子程序的运行时间的开销;
内联函数机制:编译器在编译时,将内联函数的调用以相应代码代替;
内联函数声明:inline函数原型;
注:内联函数仅在函数原型做一次声明;适用于只有1-5行的小函数;不能含有复杂结构控制语句,不能递归调用。
this 指针
一般来说,所有类方法都将this指针设置为调用它的对象的地址;
当参数与成员变量名相同时,如this->x = x,不能写成x = x。
浅复制与深复制
当类的数据成员是简单的数据类型时,创建对象时的数据复制系统机制工作得很好。但是,如果数据成员资源是由指针指示的堆,系统复制对象数据时只进行指针(地址值)复制,而不会重新分配内存空间。这样,程序运行时会产生对象操作异常;另外,当对象作用域结束后,又会错误地重复释放堆。这种情况下,需要使用用户自定义的复制构造函数。
*浅复制:
在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制;
即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容;
默认复制构造函数所进行的是简单数据复制,即浅复制 。
*深复制:
通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制;
自定义复制构造函数所进行的复制是浅复制。
静态成员:
静态数据成员在定义或说明时前面加关键字static,如:
- class A
- {
- int n;
- static int s;
- };
友元函数
用友元函数计算两点间距离
- #include<iostream>
- using namespace std ;
- #include<math.h>
- class Point
- { public:
- Point(double xi, double yi) { X = xi ; Y = yi ;}
- double GetX() { return X ; }
- double GetY() { return Y ; }
- friend double Distance ( Point & a, Point & b ) ;
- private: double X, Y ;
- } ;
- double Distance(Point & a, Point & b )
- { double dx = a.X - b.X ;
- double dy = a.Y - b.Y ;
- return sqrt ( dx * dx + dy * dy ) ;
- }
- int main()
- { Point p1( 3.0, 5.0 ) , p2( 4.0, 6.0 ) ;
- double d = Distance ( p1, p2 ) ;
- cout << "This distance is " << d << endl ;
- }
类的包含
*构造函数 ( 形参表 ) : 对象成员1(形参表 ) , … , 对象成员n (形参表 ) ;
*出现成员对象时,该类的构造函数要包含对象成员的初始化。如果构造函数的成员初始化列表没有对成员对象初始化时,则使用成员对象的无参(缺省)构造函数。建立一个类的对象时,要先执行成员对象自己的构造函数,再执行当前类的构造函数。
*用类包含计算两点间距离:
- #include<cmath>
- #include<iostream>
- using namespace std;
- class Point
- { public:
- Point( int xi=0, int yi=0 ) { x = xi; y = yi; }
- int GetX() { return x; }
- int GetY() { return y; }
- private: int x; int y;
- };
- class Distance
- { public:
- Distance( Point xp1, Point xp2 );
- double GetDis() { return dist; }
- private:
- Point p1, p2;
- double dist;
- };
学到这里我感受到了学习编程语音的压力但我也感受到了其中的快乐。
下面是我做的一道习题studentdemopic
- #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 order;}
- 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"<<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);
- void menu();
- int search(int no);
- void sortList();
- };
对于这道习题我还有很多困惑,我会在以后一一完善。
学习总结
经过这一章节的学习我学会了类这一部分很多新知识,但让我在编程方面的疑惑多了很多我认为这是一门需要不断探索的课程,我相信在我们的努力下会收获很多乐趣,也会学到很多新知识。我认为老师说的很对这一章的重要性显而易见,我认为这需要我们不断的努力。我认为所学的东西都非常浅,我的路还很长,以后也要多加努力,相信自己会做得更好!