关于类和对象

来源:互联网 发布:梦幻西游内存数据 编辑:程序博客网 时间:2024/06/03 10:58
一、类与对象
对象:具有属性和行为
封装:函数名就是对象的对外接口
抽象:类是对象的抽象,对象是类的特例
继承、重用
多态性:由继承而产生的不同派生类,其对象对同一消息会做出不同的响应
private:只能本类中的成员函数引用,类外的不能调用
public: 本类和类外都可以使用
protected:和private类似,但是派生类可以用
成员函数的定义在类外,可读性更好,如果定义在类内,则为内联函数
成员函数的存储:
一个对象所占用的空间大小只取决于该对象中数据成员占据的空间,与成员函数无关。无论是否使用inline,inline至于函数执行的效率有关系,与对象的存储空间无关。
this指针:用于指向不同对象。
1、对象成员的引用:
通过对象名成员运算符访问对象中的成员
stu1.num = 11001

通过指向对象的指针访问对象中的成员
Student t, *p;
p = &t;
p->num = 11001;
(*p).num = 11001;

通过对象的引用访问对象中的成员
Student t;
Student &t1 = t;
2、对象的初始化
如果一个类中所有的成员都是公有的,则可以在定义对象时对数据成员进行初始化,与结构体初始化类似,在花括号里顺序列出各公用数据成员的值,两个值之间用逗号隔开。但如果数据成员私有,或类中有private或protected数据成员,则不能用此方法做初始化。(用函数set)
2.1用构造函数实现数据成员的初始化
C++提供构造函数处理对象的初始化,构造函数是一种特殊的成员函数,不需要用户调用,在建立对象时自动执行。用户只需要再定义对象的同时指定数据成员的初值
构造函数名字必须与类名同名,不能任意命名,以便编译系统识别出并当作构造函数处理。不具有任何类型,没有返回值。
class Time:
{
public:
Time() //定义构造成员函数,函数名与类名相同
{
hour = 0;
m = 0;
s = 0;
}
void set_time();
void show_time();
}

class Time:
{
public:
Time();

void set_time();
void show_time();
}
Time::Time(){

}

(1) 建立类对象时会自动调用构造函数
(2)构造函数没有返回值,因此也没有类型,只是对对象进行初始化
(3)构造函数不能被用户调用也不需要被用户调用,声明为public
(4)可以用一个类对象初始化另一个类对象
Time t1;
Time t2 = t1;
不调用t2的构造函数
3、带参数的构造函数
不带参数的使对象的每一个成员在函数体中获得相同的初值。
带参数的构造函数在调用不同对象的构造函数时从外面将不同的数据传递给构造函数。
定义对象的时候带实参:
Box box1(12,25,30);
Box box2(12,22,23);

class Box
{
public:
Box(int, int, int);
int volume();
private:
int height;
int width;
int length;
};
Box:Box(int a, int b, int c)
{
height = a;
width = b;
length = c;
}
4、用参数初始化表对数据成员初始化
不在函数体内对数据成员初始化,在函数的首部实现。
Box::Box(int h, int w, int len):height(h), width(w),length(l){}
即在原来函数首部的末尾加冒号,再列出函数的初始化表,函数体为空。
如果数据成员是数组,则初始化时应在构造函数的函数体中用语句对其赋值,不能再参数列表中对其初始化。
5、构造函数的重载:
一个类中定义多个构造函数,以便为对象提供不同的初始化方法
一个类只能有一个默认构造函数(无参数的构造函数)Box box1; //Box box1()不正确
6、默认参数的构造函数
Box(int h = 10, int w = 10, int len = 10);
一般不同时使用构造函数的重载和有默认参数的构造函数
7、析构函数
作用与构造函数相反,类名前加~
对象生命期结束时,会自动执行析构函数
析构函数不返回任何类型,没有函数类型、没有函数参数。不能被重载,一个类可以有多个构造函数,但只能由一个析构函数。
i 如果函数中定义一个对象,当这个函数调用结束时,对象释放,释放前自动执行析构函数
ii 静态局部对象在main函数结束时析构
iii全局对象,退出时析构
iv new动态建立的对象,当用delete时,释放
析构函数可以用来执行”用户希望在最后一次使用对象之后所执行的任何操作“
先构造后析构、
8、对象数组
对象数组的每一个元素都是同类的对象
Student stu[3] = {
Student(1001,1,87),
Student(1002,1,87),
Student(1003,1,87),
};
建立数组对象时分别调用构造函数,对每个元素初始化
9、对象指针
9.1指向对象的指针:
对象空间的起始地址是对象的指针
Time *pt;
Time t;
pt = &t;
(*pt).hour = pt->hour
9.2 指向对象成员的指针
存放对象成员地址的指针变量。
int *p1;
p1 = &t1.hour;
9.3 指向对象成员函数的指针
与指向普通函数的指针变量定义方法不同。
普通函数 :
void (*p)(); // p是指向void型函数的指针变量
可以使p指向一个函数,并通过指针变量调用函数
p = fun; // fun函数的入口地址给p
(*p)();
成员函数:
指针变量的类型必须与赋值号右侧函数的类型匹配: 函数参数的类型和参数的个数 函数返回值类型 所属类
定义指向成员函数的指针变量:
Time t1(10, 13, 56);
void (Time::*p2)(); //定义 p2是可指向类的公有成员函数的指针变量
p2 = &Time::get_time;
(t1.*p2)();

可合写为
void (Time:: *p3)() = &Time::gettime;

10 this 指针
指向本类对象的指针,其值是当前被调用的成员函数所在的对象的起始地址。如调用a.volume时,编译系统把对象a的起始地址给this指针
this指针是隐式使用的,是作为参数传递给成员函数的

11 常对象
Time const t1(12,34,46);
常对象必须有初值
在t1的生命周期中,对象t1中所有数据成员的值都不能被改变,也可写作 const Time t1(12,23,34);
如果一个对象被声明为常对象,调用它的只能为常成员函数
void gettime() const;  //将函数声明为常成员hanshu、
常对象只能调用常成员函数,常成员函数是长对象的唯一对外接口
mutable int count  ;//可变的数据成员,可以用声明为const的成员函数修改其值

12 常对象成员
可以将对象的成员声明为const包括常数据成员和常函数成员
12.1常数据成员
只能通过构造函数初始化列表对常数据成员进行初始化,其他任何函数都不能对常数据成员赋值
const int hour;
Time::Time(int h)
{
hour = h;
}//非法

Time::Time(int h):hour(h){} //通过初始化表

12.2常成员函数
一般成员函数可以引用本类中的非const数据成员,若为常成员函数,则只能引用本类中的数据成员,不能将其修改
void gettime() const;
常对象只保真数据成员是常数

13 指向对象的常指针
将指针变量声明为const,则其指向始终保持初值,指向不变。
Time t1;
Time *const p;
p = &t1;
p = &t2;//error
指向对象的常指针值不能变,即始终指向一个对象,但可以改变其所指向的对象的值
往往用常指针做函数的形参以保证在函数的执行过程中指针始终指向原来的对象。

14 new和delete
new Box;
建立了一个Box类的对象,动态分配内存后返回一个指向新对象的指针。new动态建立的对象一般用指针访问。
15 对象的赋值和复制
赋值 用= 是指数据成员的赋值,不包括动态分配的数据
复制 用已有的对象快速复制出多个完全相同的对象: Box box2(box1); 建立对象时调用复制构造函数。
复制构造函数的参数只有一个:本类对象的引用 一般加const声明
i 程序中需要建立新对象,并用另一个同类的对象对其初始化
ii 当函数参数为类的对象时,
iii 当函数返回值是类的对象。

0 0
原创粉丝点击