1.类和对象初步

面向过程的程序设计——结构化程序设计

特点

程序=数据结构+算法

数据结构对应变量,算法对应函数;
算法用来操作数据结构;

一个大问题被分解成许多小问题的组合,也就是整个程序被分解成一个个的函数;“过程”,即由函数来实现。

缺点

  1. 难以理解和维护
    函数和它操作的变量是分离的;
    (在大型程序中,搞清楚哪些函数会访问哪些全局变量,哪些全局变量又被哪些函数访问是一件很麻烦的事情)
    函数之间的调用关系也是错综复杂的;
  2. 难以修改和扩充
    结构化程序设计中可以任意访问变量,那么当该变量的定义有改动时,所有相关的语句都要找出来修改,十分麻烦;
  3. 难以重用
    很难直接抽取出可重用的代码;
    (因为它可能会调用一些新程序用不到的其他函数,也可能会访问某些全局变量;总之就是程序的各个模块有着千丝万缕的联系,很难让某个模块的代码“独善其身”)

面向对象的程序设计

特点

程序=类+类+类+……

  1. 抽象——概括同一类事物的共同特点;
    “对象”——各种事物;

对象的特点=属性+方法
属性——变量
方法——函数
方法即为对象的行为,以及能对对象进行的操作;

  1. 封装——通过某种语法形式将数据和相应的算法捆绑,写成一个整体,“类”

类=属性(数据结构)+方法(操作数据结构的算法)

  1. 继承——新类可以从现有的类派生而来
  2. 多态——不同类的对象有名称相同的行为,而具体行为的实现方式不同

类的定义和使用

类的成员=成员变量+成员函数

类的定义

C++中“类”的定义方式

类的成员函数和定义可以分开写

可以仅在类的定义中进行成员函数的声明;
在类的外部具体写出成员函数的定义;
“类”的成员函数可以写在类的定义的外面

在定义好“类”之后定义“对象”

“对象”——通过“类”定义出来的变量
定义“对象”的基本方式——对象也就是“类变量”

对象的内存分配

  • 每个对象都有自己的存储空间
  • 成员变量是每个对象各自存有一份;一个对象的成员变量改变,不会影响另一个对象
  • 成员函数和普通函数一样,并非每个对象各自存有一份,而是在整个内存中只有一份;但它可以作用于不同的对象
  • 一个对象占用的内存空间=其成员变量的体积之和
  • 用sizeof()计算

对象间的运算

可以用“=”进行对象间的赋值;
(这个过程中实际上调用了复制构造函数,以后再详细做笔记)
但不能用各种比较运算符进行比较;(除非经过重载)

如何使用类的成员变量和成员函数

  1. 对象名.成员名;
  2. 指针->成员名;
  3. 引用名.成员名;

“成员函数作用在某个对象a上”——进入该成员函数时,函数中访问到的成员变量是属于a的;
调用类的成员函数时,必须指明它作用的对象;(否则,如果定义了多个同一类的对象,它们的成员变量名相同,但是因为每个对象各自有自己的内存空间,于是编译器不知道这个类的成员函数该访问哪个成员变量)

class和struct的区别

  • 有成员函数的struct就是class;
  • 没有成员函数的struct还是称为“结构”,这种结构变量不能算作对象;
  • 写成struct的类和写成class的类只在类成员的可访问范围上有差距;

类成员的可访问范围

访问范围说明符号

  1. private
  2. public
  3. protected
    如果没有访问范围说明符,class默认为私有,struct默认为公有。

私有成员和公有成员的区别

私有成员——只能在这个类的成员函数的内部被访问;
公有成员——在任何地方都能被访问;

换句话说,在类的成员函数的函数体内部,可以访问当前对象以及同类的其他对象的全部成员变量及函数;在外部,只能访问该类对象的公有成员。

实例

//定义一个名为“CEmployee”的类
class CEmployee {
private:
	char szName[30];
public:
	int salary;
	void setName(const char *name);
	void getName(const char* name);
	void averageSalary(CEmployee e1, CEmployee e2);
};

szName是一个私有的成员变量;
salary是一个公有的成员变量;
在外部定义其成员函数如下:

void CEmployee::setName(const char *name)
{
	strcpy(szName, name);
	//OK!在成员函数内部,可以访问私有成员szName;
}
void CEmployee::getName(const char *name)
{
	strcpy(szName, name);
	//OK!在成员函数内部,可以访问私有成员szName;
}
void CEmployee::averageSalary(CEmployee e1, CEmployee e2)
{
	salary = (e1.salary + e2.salary) / 2;
	//OK!在成员函数内部,可以访问同类的其他对象的成员;
}

下面看主函数,它在成员函数的外部。

int main()
{
	CEmployee e;//定义对象e
	strcpy(e.szName, "Tom");
	//WRONG!在成员函数外部,不能访问其私有成员szName!
	e.setName("Tom");
	//OK!在成员函数外部,可以访问其公有成员函数
	e.salary = 5000;
	//OK!在成员函数外部,可以访问其公有成员变量
	return 0;
}

隐藏——设置私有成员的机制

  1. 利于程序修改
    强制对私有成员变量的访问通过成员函数进行;好处是:如果以后成员变量的类型的属性修改了,只需要修改成员函数,而不用找出所有的函数中直接访问成员变量的语句进行修改;
  2. 避免对成员对象的不正确操作

内联成员函数

两种实现

func1,func2都是内联成员函数

  1. 在声明成员函数的时候加上Inline关键字;
  2. 直接将成员函数的函数体写在类的定义里面;
    相当于用空间换时间。
    当该函数本身语句较少,在程序中要反复调用,并且调用它的时间开销如果不能小于它的执行开销,那么不如写成内联函数;但如果一个函数本身执行时间就很长,调用它的开销只是一小部分,那么写成内联函数就只会带来额外的内存开销。

注意事项

类的定义

成员变量不能为自身类型,但可以是自身类型的指针或引用。
原因见链接:
为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?.
从内存分配的角度来说,当类的定义还没有完成的时候,编译器是无法计算给当前类的对象分配多少空间的,于是会出错;但是指针或者引用(引用的本质是指针常量),它们的空间是固定的,与类型无关。
从对象构造的角度来说,会出现无限初始化的现象。(详见构造函数的相关讲解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值