一.类的定义
*类是对具有相同属性和行为的一组对象的抽象与统一描述
*类的定义包括行为和属性两个部分
*属性以数据成员表示,行为通过成员函数实现
定义格式
class 类名
{
private:
私有数据成员和成员函数
protected:
保护数据成员和成员函数
public:
公共数据成员和成员函数
};
注意:
*类的成员可以是其他类的对象,但不能以类自身的对象作为本类的成员,而类自身的指针和引用可以作为类的成员
*类定义必须以分号“;"结束
*类与结构体的区别:
没有明确指定类成员的访问权限时,C++结构体的成员是公有的,而类的成员是私有的
类的访问属性
public 公有成员 类的外部接口
protected 保护成员 仅允许本类成员及派生类成员函数访问
private 私有成员 仅允许本类成员函数访问
二.成员函数
类的成员函数是实现类的行为属性的成员
一般将成员函数声明为函数原型(在类内进行声明),在类外具体实现成员函数(在类外定义)
成员函数的定义
返回值类型 类名::成员函数名(参数表)
{
函数体
}
注意:
1.在类的定义中不能对数据成员进行初始化2.类的任何成员都必须指定访问属性,一般将数据成员定义为私有或保护成员,将成员函数定义为公有成员
3.类中的数据成员可以是c++语法规定的任意数据类型
4.类的成员可以是其他类的对象,成为类的组合,但不能以类自身的对象作为本类的成员
5.类定义必须以分号结束
6.class,成员缺省情况是private;struct中成员缺省情况是public
重要的成员函数:
1.构造函数
构造函数是用于创建对象的特殊成员函数,当创建对象时,系统自动调用构造函数
构造函数的作用:为对象分配空间;对数据成员赋初值;请求其他资源
没有用户定义的构造函数时,系统提供缺省版本的构造函数,构造函数名与类名相同
析构函数可以有任意类型的参数,但没有返回类型,可以进行重载
**对象:对象是类的实例或实体,类与对象的关系,如同c++基本数据类型和该类型的变量之间的关系
定义格式: 类名 对象名1,对象名2......;必须在定义了类之后,才可以定义类的对象
**函数重载:函数名相同,但参数不相同的一组函数,编译器根据不同的参数类型和个数调用这组函数 用于处理不同数据类型的类似任务
2.复制构造函数
用一个已有同类对象创建新对象进行数据初始化,保护实参对象只读
c++为类提供默认版本的复制构造函数
程序员可以定义用户版本的复制构造函数 语法形式 类名::类名(const 类名&引用名,....);
浅复制与深复制:
在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式为浅复制
即:对于复杂类型的数据只复制了存储地址而没有复制存储内容,默认构造函数所进行的是简单数据复制,即浅复制。
通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式叫做深复制
2.析构函数
析构函数是用于取消对象的成员函数,当一个对象作用域结束后,系统自动调用析构函数
析构函数的作用:进行消亡对象的清理工作
没有用户定义的析构函数时,系统提供缺省版本的析构函数,析构函数名:~类名,析构函数没有参数和返回类型
通常利用构造函数创建对象有两种方法
(1).利用构造函数直接创建对象,其一般形式为:类名 对象名[(实参表)];
(2).利用构造函数创建对象时,通过指针和new来实现,语法形式:类名 *指针变量名=new类名[(实参表)];
例如:Date *date1=new Date(1998,4,28);
就创建了对象(*date1)
构造函数初始化成员的两种方式
a.使用构造函数的函数体进行初始化
class Date
{
int d,m,y;
public:
Date(int dd,int mm,int yy)
{
d=dd;m=mm;y=yy;
}
};
b.使用构造函数的初始化列表进行初始化
class Date
{
int d,m,y;
public:
Date(int dd,int mm,int yy):d(dd),m(mm),y(yy)
{
}
};
必须使用参数初始列表对数据成员进行初始化的几种情况:数据成员为常量、数据成员为引用类型、数据成员为没有无参构造函数的类的对象
类按照数据成员在类中的声明顺序进行初始化,与初始化列表中出现的顺序无关
三.类的其他成员
1)常成员
常数据成员是指数据成员在实例化被初始化后,其值不能改变
在类的成员函数后面可以加const关键字,则该成员称为常成员函数
class Student
{
public:
Student(int y,int m,int d,int num=0,string name="noname");
void PrintStudent()const;//常成员函数
private:
const int code;//常数据成员
string name;
Date birthday;//结构数据成员
};
2)常对象
如果在说明对象时用const修饰,则被说明的对象为常对象
常对象的说明方式:类名 const 对象名[(参数表)];或者const 类名 对象名[(参数表)];
在定义常对象时必须进行初始化,而且不能被更新
c++不允许直接或间接更改常对象的数据成员
c++规定常对象只能调用它的常成员函数、静态成员函数、构造函数(具有公有访问权限)
3)常成员函数
在类中使用关键字const说明的函数为常成员函数,
说明格式:类型说明符 函数名(参数表)const
4)静态成员
类成员冠以static声明时,称为静态成员
静态数据成员为同类对象共享
静态成员函数与静态数据成员协同操作
静态成员不属于某一个单独的对象,而是为类的所有对象所共有
静态成员函数的作用:不是为了对象之间的沟通,而是为了能处理静态数据成员:在保证不依赖于某个对象的前提下,访问静态数据成员
静态数据成员声明及初始化:
在类外进行静态数据成员的声明:类型 类名::静态数据成员[=初始化值];//必须进行声明
不能在成员初始化列表中进行初始化
如果未进行初始化,则编译器自动赋初值默认值为0,初始化时不能使用访问权限
设计包含静态数据成员和静态成员函数的类:
某商店经销一种货物,货物成箱进,成箱卖出,购进和卖出都是以重量为单位(每箱的重量不同),商店需记录下存货的总重量
分析:定义一个
货物类,表示一箱货物,类中包含私有成员 weight;
一个静态数据成员total_weight;
定义in函数,表示进货,进货时
total_weight的值增加
定义out函数,表示出货,出货时
total_weight的值减少
定义静态函数display_store()函数,显示当前的库存货物总重量
#include<iostream>
using namespace std;
class Goods
{
int weight;
static int total_weight;
public:
Goods(int x):weight(x){}
void in(){total_weight=total_weight+weight;}
void out(){total_weight=total_weight-weight;}
static void display_store(){cout<<total_weight<<endl;}
};
int Goods::total_weight=0;
int main()
{
Goods g1(10).g2(20);
g1.in();g2.in();
Goods::display_store();
g1.out(); Goods::display_store();
return 0;
}
说明:
1.静态成员函数在类外定义时不用static前缀
2.静态成员函数主要用来访问同一类中的静态数据成员
3.私有静态成员函数不能在类外部或用对象访问
4.可以在建立对象之前处理静态数据成员
5.编译系统将静态成员函数限定为内部连接(在其他文件中不可见)
6.静态成员函数中没有this指针
7.静态成员函数不访问类中的非静态数据成员,如有需要,只能通过对象名(或指向对象的指针)访问该对象的非静态成员
***this指针
需要this指针的三种情况
1.在类的非静态成员函数中返回类对象本身或对象的引用的时候,直接使用return *this;返回本对象的地址时,return this
2.当参数与成员变量名相同时,如this->x=x,不能写成x=x
3.避免对同一对象进行赋值操作,判断两个对象是否相同时,使用this指针
友元函数
如果在本类(类A)以外定义了一个函数(函数B),这个函数可以是不属于任何类的非成员函数,也可以是体其他类的成员函数
在类体中用friend对其(函数B)进行声明,此函数就称为本类(类A)的友元函数,可以访问这个类的私有成员
类的包含(类的组合)
**类的包含是程序设计中一种软件重用技术,即定义一个新的类时,通过编译器把另一个类“抄进来”
**当一个类中含有已经定义的类类型成员,带参数的构造函数对数据成员初始化,需使用初始化语法格式
构造函数(形参表):对象成员1(形参表),....
对象数组
指每一数组元素都是对象的数组
定义格式:类名 数组名[下标表达式];