类的总结

在面向对象程序设计中,程序的基本本单位是类。具有相同性质和功能的东西构成的集合,通常归为一类;c++中,属性用数据的储存结构实现,成为类的数据成员;方法用函数实现,称为函数成员。
c++中,类定义的说明语句一般形式为:
Class<类名>
{
Public:
公有段数据成员和成员函数
Protected:
保护段数据成员和成员函数
Private:
私有段数据成员和成员函数
};(分号在类定义结束后一定要有)
class是定义类的关键字。"类名"是用户自定义的标识符,用于标识类型的名字。一对花括号相括说明类的成员,以分号结束类定义语句[必须加]。
private:用于声明私有成员,只能在类中可见,但也可以放在public中,省略关键字private。
protected:声明保护成员。
public:声明公有成员,公有成员是类的接口。
各种不同访问性质的成员说明段在类定义中没有顺序规定,也可以重复出现。一般顺序如上图可见。除了clasa外,关键字struct也可用于定义。用struct定义类时,如不特别指出,则所有成员都是共有的。
列:class Date
  {public:
         void setDate(int y,int m,int n);
         int IsLeapYear();
         void printDate();
   private:
          int year,month,day;
   };
    成员函数在类外定义使用作用域区分符进行说明,此时函数头的形式为:返回值类型  类名::函数名(参数表)
Date累的定义成员函数定义再累外写成:
void   Date ::SetDate(int y,int m,int n)
{year=y;
month=m;
day=n;
}
int  Date::IsLeapYear()
{return (year%4==0&&year%400!=0)||(year%400==0);}
void  Date::PritDate()
{  cout<<year<<"."<<month<<"."<<endl;}
累的数据成员除了基本类型外,还可以有数组,结构,类等自定义的数据类型。如:
class student
{public:
  char  name[10];
Date brithday;
long  code;
char *address;
char  phone[20];
};
如有说明:stu.brithday.SetDate(1985.1.15);
6.1.2   访问对象成员
使用对象包括访问对象成员的数据成员和调用成员函数。访问对象的访问形式与访问结构的形式相同,运算符"."和"->"用于访问对象成员。
访问对象的公有成员。
#include<iostream>
using namespace std;
class Tclass
{public:
      int x,y;
      void prite()
      {  cout<<x<<","<<y;};
};
int main()
{ Tclass tese;
test.x=100;//访问公有端数据成员
test.y=200;
test.print();//调用公有段数据成员
}
#include <iostream>
#include<cstdio>
using namespace std;
class  Tclass
{  public:
      int x,y;
      void print()
      { cout<<x<<","<<y<<endl;}
};
int add(Tclass *pt)
{  return (pt->x+pt->y);}
int main()
{
    Tclass test ,*pt=&test;//说明一个对象test和对象指针pt
    pt->x=100;//用对象指针访问数据成员
    pt->y=200;
    pt->print();//对象指针调用成员函数
    test.x=150;
    test.y=450;
    test.print();
    cout<<"x+y"<<" "<<add(&test)<<endl;//把对象地址传递给指针参数
}
6.1.3   this指针
this指针在类内使用,指明对象本身。this指针的显示使用主要在运算符重载、自引用等场合。this指针是一个长指针,相当于:class_Type*conat this
6.2 .1简单构造函数和折构函数
构造函数是用于创建对象的特殊成员函数。当创建对象时,系统自动调用构造函数。
构造函数的作用是:
为对象分配空间;对数据成员赋初值;请求其他资源
没有用户定义的构造函数时,系统提供缺省版本的构造函数。
构造函数名与类名相同:类名。构造函数可以重载
构造函数可以有任意类型的参数,但没有返回类型。
析构函数是用于取消对象的成员函数,当一个对象作用域结束时,系统自动调用析构函数,析构函数的作用是进行对象消亡时的清理工作,没有用户定义析构函数时,系统提供缺省版本的析构函数。如:类名::类名(){}。但当用户定义了构造函数时缺省的函数不在构造。
析构函数名为: ~ 类名如~Date();
析构函数没有参数,也没有返回类型。
***通过SetDate,我们可以多次重置数据成员的值,但折构函数不能通过对象显示使用,他仅用于创建对象和数据初始化。同时对象的构造次序和折构次序是相反的首先创建的对象将最后折构。
如果对象是由new运算符动态创建的。delete运算会自动调用折构函数。如:
int main()
{Date *pd;
pd=new Date(1982,6,6);
pd->PrintDate();
delete(pd);//调用折构函数
}new动态创建的对象如果不用delete释放,将会出现内存泄露。
6.2.3  重载构造函数
构造函数与普通函数一样,允许重载。如果Date累具有多个构造函数,创建对象时,将根据参数匹配调用其中的一个。
列如:
class   Date
{public:
Date ();
Date  (int);
Date  (int ,int);
~Date ();
};
void  f()
{Date d;//调用Date()
Date  d1(2000);//Date  (int)
}
6.2.4  复制构造函数
创建对象时,有时希望用一个同类型对象的数据对他进行初始化。c++可以完成类对象数据的简单复制。复制构造函数要求有一个类类型的引用参数;
          类名::类名(const  类名  &  引用名,.....);
为保证所引用不被修改,通常把引用参数说明为const参数。例如:
Class A
{
Public:
A(int);
A(const A&,int=1); //复制构造函数
}
A a(1);   //创建对象a,调用 A(int)
A b(a,0);  //创建对象b,调用A(const A&,int=1);
A c=b;   //创建对象c,调用A(const A&,int=1);}
复制构造函数的特点;
(1)、复制构造函数名与类名相同,并且也没有返回值类型。
(2)、复制构造函数可写在类中,也可以写在类外。
(3)、复制构造函数要求有一个类类型的引用参数。
(4)、如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。
②深复制与潜复制
复制构造函数用一个已有同类对象创建新对象进行数据初始化
C++为类提供默认版本的复制构造函数
程序员可以定义用户版本的复制构造函数
语法形式
类名 :: 类名(const 类名 & 引用名 , …);
复制构造函数的特点:
1.复制构造函数名与类名相同,并且也没有返回值类型。
2.复制构造函数可写在类中,也可以写在类外。
3. 复制构造函数要求有一个类类型的引用参数。
4.如果没有显式定义复制构造函数,系统自动生成一个默
认形式的复制构造函数。
复制构造函数的调用,以下三种情况下由编译系统自动调用:
1.声明语句中用类的一个已知对象初始化该类的另一个对象时。
2.当对象作为一个函数实参传递给函数的形参时,需要将实参对象去初始化形参对象时,需要调用复制构造函数。
3.当对象是函数的返回值时,由于需要生成一个临时对象作为函数返回结果,系统需要将临时对象的值初始化另一个对象,需要调用复制构造函数。
   例子:#include <iostream>
using namespace std;
class Box
{
public:
Box(int =10, int =10, int =10);
Box(const Box & b)
{height=2*b.height; width=2*b.width;length=2*b.length;}
int volume();
private:
int length, height, width;
};
Box::Box(int h, int w, int l):length(l),width(w),height(h){ }//构造函数初始化列表,给内容赋值
int Box::volume (){ return width*height*length;}
int main()
{
Box box1(1,2,3),box2(box1),box3=box2;
cout<<"Box1's volume is "<<box1.volume()<<endl;
cout<<"Box2's volume is "<<box2.volume()<<endl;
cout<<"Box3's volume is "<<box3.volume()<<endl;
return 0;

②深复制与潜复制
关于浅复制:
●在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容
●默认复制构造函数所进行的是简单数据复制,即浅复制
关于深复制:
1.通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
2.自定义复制构造函数所进行的复制是浅复制。
3.深复制构造函数必须显式定义
深复制构造函数的特点:
1.定义:类名::类名([const] 类名 &对象名);
2.成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作.
6.3    类的其他成员
6.3.1  常成员
1.在类中,定义常成员用const约束。常数据成员是指数据成员在实例化被初始化后约束为只读;常成员函数是指成员函数的this指针被约束为指向常量的长指针,在函数体内不能修改数据成员的值。
①由构造函数直接用常量初始化常数据成员
例如:Mclass():M(5){}
ps:不能在类外修改数据成员
②用带参数的构造函数初始化常数据成员
例如:
#include <iostream>
#include <cstring>
using namespace std;
struct Date
{ int year,month,day;};
class Student
{public:
    Student(int y,int m,int d,int num=0,char *pname="no mane");
    void PrintStudent()const;//常成员函数
private:
    const int code;//常数据成员
    char name[20];
    Date birthday;//结构数据成员
};
void Student::PrintStudent()const
{ cout<<"序号: "<<code<<"\t姓名: "<<name<<"\t"<<"出生日期: "<<birthday.year<<"-"<<birthday.month<<"-"<<birthday.day;
  cout<<endl;
}
//带参数构造函数完成数据成员初始化
Student::Student(int y,int m,int d,int num,char*pname):code(num)
{  strcpy_s(name,pname);
   name[sizeof(name)-1]='\0';
   birthday.year=y;
   birthday.month=m; 
   birthday.day=d;
}
int main()
{Student stu1(1990,3,21,1001,"陈春");
stu1.PrintStudent();
Student stu2(1985,10,1,1002,"张庆华");
stu2.PrintStudent();
}
2.常对象
若在定义对象的说明语句以const作前缀,则该对象称为常对象。这个对象的全部数据成员在作用域中约束为只读不写。
3.常成员函数
class X
{  int a;
   int g() const//常成员函数
    {return a++;}//错误,不能修改数据
};在类X中,成员函数g首部以关键字const作为后缀,成为"常成员函数",相当于常成员函数的this指针类型为:
            const X *const this
6.3.2 静态成员
1.类成员冠以static声明时,称为静态成员。
2.静态数据成员为同类对象共享。
3. 静态成员函数与静态数据成员协同操作。
静态成员函数:
1.静态成员不属于某一个单独的对象,而是为类的所有对象所共有.
2.静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员: 保证在不依赖于某个对象的情况下,访问静态数据成员.
定义静态成员函数的格式如下:
          static 返回类型 静态成员函数名(参数表);
与静态数据成员类似,调用公有静态成员函数的一般格式有如下几种:
类名::静态成员函数名(实参表)
对象. 静态成员函数名(实参表)
对象指针->静态成员函数名(实参表)
ps:说明:
(1)静态成员函数在类外定义时不用static前缀。
(2)静态成员函数主要用来访问同一类中的静态数据成员。
(3) 私有静态成员函数不能在类外部或用对象访问。
(4)可以在建立对象之前处理静态数据成员。
(5)编译系统将静态成员函数限定为内部连接(在其他文件中不可见)。
(6)静态成员函数中是没有this指针的。
(7)静态成员函数不访问类中的非静态数据成员。如有需要,只能通过对象名(或指向对象的指针)访问该对象的非静态成员。例如下题:
#include<iostream.h>
class small_cat
{public:
     small_cat(double w) { weight=w;total_weight+=w;total_number++;}
     static void display(small_cat &w)
     {cout<<"The small_cat weights "<<w.weight<<"kg\n";}
     static void total_disp()
     {cout<<total_number<<"small_cat total weight ";
       cout<<total_weight<<" kg "<<endl;}
private:
     double weight;  
     static double total_weight;static double total_number;
};
double small_cat::total_weight=0;double small_cat::total_number=0;
int main()
{    small_cat w1(0.9),w2(0.8),w3(0.7);
      small_cat::display(w1);small_cat::display(w2);
      small_cat::display(w3);small_cat::total_disp();
      return 0;
}
6.4  类的包含

1.①类的包含是程序设计中一种软件重用技术。即定义一个新的类时,通过编译器把另一个类 “抄”进来。
②当一个类中含有已经定义的类类型成员,带参数的构造函数对数据成员初始化,须使用初始化语法形式。
如:构造函数 ( 形参表 ) : 对象成员1(形参表 ) , … , 对象成员n (形参表 ) ;
2.数据成员的初始化
①出现成员对象时,该类的构造函数要包含对象成员的初始化。如果构造函数的成员初始化列表没有对成员对象初始化时,则使用成员对象的无参(缺省)构造函数。
②建立一个类的对象时,要先执行成员对象自己的构造函数,再执行当前类的构造函数。
学习心得:                                                                                                                                                                                在类的学习中,我了解了啥是类,成员函数等相关知识,但不能够正常使用。所以现在主要还是在课件,老师提供的例题和课本中的知识进行学习。来弥补学习中漏掉的知识点,对于编写程序还有困难。所以在所学的知识中,还有很多不是很了解,有的甚至就根本不懂。所以课件总结的不是很好。这一章中教给我们复杂程序,而上一章中,主要偏向于基础知识。由于这一章所学东西较多,所以显得繁琐,在学习中表现出厌烦情绪,走神的情况也较多 ,在接下来的学习中,努力全身心投入进去。
对于现阶段的学习,程序的编写不仅依靠于主函数,还有不止一个的类,所以在编写过程中不仅要仔细思考,还要一个一个的调试,每一个类都尽量保持正确,要想滚雪球一样。              

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值