一 类和对象
1概念特点
描述事物的属性在类中用变量表示出来,该事物所进行的操作在类中用函数表示出来.(抽象),该变量与函数以类的形式捆绑在一起显示出密切关系,叫"封装".面向对象四大特点:抽象,封装,继承,多态.类可通俗的理解为带函数的结构体.
2对象
1内存分配
和结构体类似,对象所占的内存空间大小,为所有成员变量的大小之和.但是类最小的存储单元按类中变量占用字节最大的算.
class app{
public:
int a;double d;
private:
int b;
};
int main(){
app c;
cout<<sizeof(c);
//double占8个,int占4个,显示24.因为一个double占8个字节
类中有三个变量,三个存储单元,都按8算
2对象间的运算
与结构体一样,对象间不可用关系运算符(==,>等)进行比较,除非这些运算符经过了"重载"
3类中公有成员的访问
1对象名.成员名:
app zqq;
zqq.n1;
2指针 -> 成员名:
//指针
app zqq;
app* p1=&zqq;
p1->n1=1;
3引用名.成员名:
//引用
app zqq;
app& zqq1=zqq;
zqq1.n1=1;
4类中私有成员的访问
1在类的成员函数的内部,能够访问当前对象的全部变量,函数,同一类的其他对象的全部变量,函数.
class student{
public:
string name;
void scanfgrades(int n);
void printfgrades();
void average(student e1,student e2);
private:
int grades;
};
void student::scanfgrades(int n){
grades=n;
}
void student::printfgrades(){
cout<<grades;
}
int main(){
student a;
a.scanfgrades(99);
a.printfgrades();
成员函数可以重载和函数缺省值.
3构造函数
1概念:
1构造函数是成员函数的一种,但名字与类名相同,可有参数,不可有返回值.
2作用是对对象进行初始化.
3如果类在定义时没写构造函数,编译器会自动生成.
4对象在生成时构造函数自动被调用,对象一旦生成,就不可在其上执行构造函数.
2作用:
构造函数执行必要的初始化工作,可对类中的数据成员赋初始值.
3注意:
1构造函数可以进行重载,可以有缺省值.
2如果构造函数有参数,那么在建立对象时要有相应的参数,把他们作为初始值.如果构造函数没有参数,类不加括号了.例如:
class box{
private:
int height;int kuan;
public:
box(int a,int b);
};
int main(){
box b1(1,7);//定义类时自动调用构造函数,此段简写!!!
/*
若class中为box();
在定义类时应写为box b1;
*/
4构造函数在数组中的使用:
类的定义:
class stu{
int grades;
public:
stu();//构造1,单纯这样写构造函数会编译错误
stu(int a);//构造2
stu(int a,int b);//构造3
};
在main函数中:
1 stu a1[2];
数组的两个元素均为(stu型),且在生成时都调用的构造1;
2 stu a2[2]={1,2};
数组的两个元素都是调用构造2;
3 stu* a3=new stu[2]
动态分配一个具有2个stu型对象的数组,且其元素(类)都调用的构造1;
4 stu a4[3]={1,stu(1,2)}
数组元素分别用构造2,构造3,构造1进行初始化;
5 stu* a5[3]={new stu(1),new stu(1,2)}
定义了指针数组,即生成了三个(stu指针型)的数组,数组的元素按构造2,构造3进行初始化.a5[2]没被初始化,它依然只是个指针.
4析构函数
1概念:
1格式: ~ 类名 () : 没有返回值,一个类最多只有一个.
2析构函数在对象消亡时自动被调用,可定义析构函数来在对象消亡前做些工作,比如释放分配的空间.
3如果定义类时没写析构函数,那么编译器会自动生成缺省的析构函数,此函数什么都不做.
4同构造函数一样,在类外定义析构函数时,格式是: 类名::类名,因为它也是无返回值.
2实例:
class stu{
private:
char* name;
public:
stu(){
name=new char[10];
}//构造函数
~stu();//析构函数
};
stu::~stu(){
delete [] name;cout<<"1213";
//分配的空间正好在对象结束前被释放.
}
//该类定义的对象在结束前执行~stu,输出1213.
接下来分析析构函数被调用的情况:
1普通的主函数rerun,只要有对象消亡就有析构函数调用;
2动态分配一个某种类的对象或对象数组时,例如以下:
class stu{
...
};
stu* p;
p=new stu;//p=new stu[2];对象数组
delete p;//delete [] p;
那么在new时,它调用了构造函数,在delete时,调用了析构函数.
3对象作为函数的返回值返回后被调用:
class stu{
public:
~stu(){
cout<<"被调用"<<endl;
}
};
stu a1;
stu function(stu x){
cout<<"123"<<endl;
return x;
}
int main(){
a1=function(a1);
return 0;
}
输出:
123
被调用//函数调用返回形参stu x的消亡
被调用//函数调用返回时生成的临时对象的消亡,对应标题
被调用//全局变量main函数返回a1的消亡
(补:一个函数在调用返回后会释放他的参数,局部变量) 注意:new出的对象或者对象数组,如果没有被完全delete掉,就算main函数结束也不会调用析构函数.
867

被折叠的 条评论
为什么被折叠?



