知识点:
类的定义1.类是对具有相同属性和行为的一组对象的抽象与统一描述。是用户自定义的数据类型
2.类的定义包括行为和属性两个部分。
3.属性以数据表示,行为通过函数实现。
定义格式:
class 类名
{
public://用来与外界交互的数据和函数
公有数据成员和成员函数;
protected:
保护数据成员和成员函数;
private: //可以保护的数据,除了自己类的函数可以使用,其他的函数不能对其修改
私有数据成员和成员函数;
};
例子:class Student //定义学生类Student
{
public: //声明类成员
void Getinfo(string pname, string pid
,char Sex, inta,double s);//函数用来获得学生的信息
void modify(float s);
void display();//用来展示被保护的数据
private:
string name;//这里的姓名等为私有数据
string id;
char sex;
int age;
double score;
};//最重要的一点是不要忘了这个分号
注意事项:类的成员可以是其他类的对象,但不能以类自身的对象作为本类的成员,而类自身的指针和引用可以作为类的成员。
没有明确指定类成员的访问权限时,C++结构体的成员是公有的,而类的成员是私有的。
就是说把私有成员放在开头不声明类型时,认为为私有类。
各种不同访问性质的成员再说明段在类定义中没有顺序规定,也类定义中没有顺序规定,也可以重复出现。为了方便了解接口,往往把共有段成员放在开始位置。
成员函数在类外定义使用作用域区分符进行说明,形式为:
返回类型 类名::参数名(参数表)
其中作用域用::表示,用来表示那一个类的函数。
而成员函数的作用为:一是操作数据成员,包括访和修改数据成员。二是用于协同不同的数据成员操作,成为传递信息。
对象:对象类类型的变量,也想当于类的实体。
类与对象的关系,如同C++基本数据类型和变量的关系。像是自己定义了一种类,自己控制着种类的内容,来满足自己的需要。
而类的数据成员可也是基本的类型外,还可以是数组,结构,类等自定义的数据类型。
甚至可以是自己定义的类的对象.这种形式称为类的包含。
classPoint //定义一个point类用来记录一个点的特征
{float P1_x,P1_y;
public:
void InitPoint(float PointA_x, floatPointA_y);
void Move(float New_x, float New_y);
float GetPointx();
float GetPointy();
};
intmain()
{
Point p1,p2;//p1 p2 为具有这种类的特征的两个点
}
类成员的访问形式
包括 圆点和指针这两种形式
圆点S.display();
指针 对象指针变量名—》公有成员
指针:当一个对象调用类的成员函数时,对象的地址被传给this指针,this指针指向被调用成员。This是隐含指针不能显式使用。当this指针一旦被初始化,就不能在进行修改和赋值,以保证不会指向其他的成员。
#include<iostream.h>
class ptr_access {
public:
void setvalue(float a, float b) { x=a; y=b; }
float Getx() {return x;}
float Gety() {return y;}
void print()
{
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
private: //私有数据成员
float x,y;
};
intmain()
{
float a1,a2;
ptr_access *ptr=new ptr_access;
ptr->setvalue(2,8);
//通过指针访问公有成员函数
ptr->print();
a1=(*ptr).Getx();
//通过公有成员函数访问私有数据成员
a2=(*ptr).Gety();
cout<<"a1="<<a1<<endl;
cout<<"a2="<<a2<<endl;
return 0;
}
写一个程序,输入矩形的长和宽,输出面积和周长
分析:将长、宽变量和设置长,宽,求面积,以及求周长的三个函数“封装”在一起,就能形成一个“矩形类”。
长、宽变量成为该“矩形类”的“成员变量”,三个函数成为该类的“成员函数”
classCRectangle
{
public:
int w,h;
int Area() {
return w * h;
}
int Perimeter() {
return 2 * ( w + h);
}
void Init( int w_,int h_ ) {
w = w_; h = h_;
}
};
intmain( )
{
int w,h;
CRectangle r; //r是一个对象
cin >> w >> h;
r.Init( w,h);
cout << r.Area() << endl <<r. Perimeter();
return 0;
}
- 在类的定义中不能对数据成员进行初始化。
- 类的任何成员都必须指定访问属性,一般将数据成员定义为私有成员或保护成员,将成员函数定义为公有成员。
- 类中的数据成员可以是C++语法规定的任意数据类型。
- 类的成员可以是其他类的对象,称为类的组合。但不能以类自身的对象作为本类的成员。
- 类定义必须以分号“;”结束
- class与struct的不同:
① class中,成员缺省情况是private。
② struct中,成员缺省情况是public。
知识点:内敛函数
作用 减少频繁调用小子程序的时间开支。
机制 编译器在编译时,,将内联函数的调用以相应代码代替。
声明 inline 函数原型
注意内联函数在函数原型作一次说明。
适用于只有1-5行的小函数
不能含有复杂结构控制结构语句,不能递归调用。
在整理这个知识点时,才意识到之前自己的做法是错误的,自己以前经常在类函数内进行大量的操作。
classCoord{
public:
void setCoord(int a,int b)
{ x=a; y=b;}
int getx()
{ return x;}
int gety()
{ retrun y;}
private:
int x,y;
};
函数重载:函数名相同,但是参数不同(类型不同,或者个数不同)的一组函数。
函数重载用于处理不同数据类型的类似任务
实例:
#include<iostream>
usingnamespace std ;
int abs ( int a ) ;
double abs ( double f ) ;//对于相同的函数 不同的参量,调用不同的函数
intmain ()
{ cout<< abs ( -5 ) << endl;
cout << abs ( -7.8 )<< endl ;
}
int abs ( int a )
{ return a < 0 ? -a : a; }
double abs ( double f )
{ return f < 0 ? -f : f ; }
这里有一个重载解决小问题的函数
#include<iostream>
usingnamespace std ;
int max ( int a , int b ) ;
int max ( int a , int b, int c ) ;
intmain ()
{ cout << max ( 5, 3 ) <<endl ;
cout << max (4, 8, 2 )<< endl ;
}//对于不同个数比较要求 调用不同的函数
int max ( int a , int b )
{ return a > b ? a : b ; }
int max ( int a , int b, int c)
{ int t;
t = max ( a , b ) ;
return max ( t , c ) ;
}
构造函数和析构函数
构造函数是用于创建对象的特殊成员函数
当创建对象时,系统自动调用构造函数
作用 为对象分配空间,对数据成员赋值,请求其他资源
没有用户定义的构造函数时,系统提供缺省版本呢的构造函数。
构造函数名与类名相同:类名
构造函数可以重载
构造函数可以有任意类型的参数,但没有返回类型。
同时,构造函数是可以重载的。
与构造函数对应的,是析构函数。对于析构函数的使用,后面也有详细的介绍和使用。
析构函数用于取消对象的成员函数。当一个对象作用域结束时,系统自动调用析构函数。
当没有用户定义的析构函数时,系统提供省却版本的析构函数。
析构函数名为~类名。
析构函数没有参数,也没有返回类型。
如果类中没有定义的构造函数,系统将自动生成一个默认形式的构造函数,用于创造对象,默认构造函数形式。
类名::类名(){}
默认构造函数时是一个空函数。
构造函数和析构函数不应该定义在私有部分。因为对象必须在类说明外创建和撤销。
#include<iostream.h>
classDate {
public:
Date(); // 无参构造函数
Date(int y,int m,int d);
void showDate();
private:
int year, month, day;
};
Date::Date() // 构造函数的实现
{ year=0; month=0; day=0; }
Date::Date(inty,int m,int d)
{year=y; month=m; day=d; }
inlinevoid Date::showDate()
{ cout<<year<<"."<<month<<"."<<day<<endl;}
intmain()
{
Date a_date,bDate(2014,3,25);
a_date.showDate();
b_date.showDate();
return 0;
}
(1) 利用构造函数直接创建对象.其一般形式为:
类名 对象名[(实参表)];
这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。
intmain()
{
Date *date1;
date1=new Date(1998,4,28);
// 以上两条语句可合写成:Date *date1=new Date(1998,4,28);
cout<<"Date1 output1:"<<endl;
date1->showDate();
delete date1;
return 0;
}
利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:
类名 *指针变量 = new 类名[(实参表)];
例如:
Date *date1=new Date(1998,4,28);
就创建了对象(*date1)。
带参数的构造函数在建立一个对象时,可以用指定的数据初始化对象的数据成员。
调用参数化的构造函数,创建了两个对象。构造函数与成员函数,的作用和调用时机不同,例如,我们呢可以用setDate重复对一个成员进行赋值操作,但是构造函数,只是在创建对象时,调用和初始化赋值。而且构造函数不能显示使用。另外注意,构造函数和析构函数的次序时相反的,即先创建的函数最后析构。
当对象是有new运算动态符所创建的,delete运算会自动调用析构函数。
当new动态运算符创建的对象如果不用delete释放,即使建立对象的函数执行结束,系统也不会调用析构函数,这样会导致内存泄漏。
构造函数的初始化列表————数据成员的初始化
有两种方法:
1. 使用构造函数的函数体进行初始化
2. 使用构造函数的初始化列表进行初始化
3. class Date//使用构造函数的函数体进行初始化
4.