我对面向对象编程的一些理解-创新互联
- 1. 面向对象编程的主导问题
- 2. 访问指定符
- 3. const
- 4. 类的静态数据成员
- 5. 类的操作
- 6. 运算符重载
- 7. 继承
- 8. 虚函数和多态
- 9. 输入输出操作
- 10. 标准模板库 STL
1. 面向对象编程的主导问题
- C++三大特性
- 封装、继承、多态。
- 封装:目的是实现代码模块化。
- 继承:目的是实现代码扩展。
- 多态:目的是分为静态多态和动态多态。
- 什么是程序?
- what: 一段编译器能听懂的指令
- input ---->process —>output
- why: 自然语言有歧义,用于计算机运算效率不高
- how: 根据问题,构建数据类型+算法---------------如何写好代码?
- 什么是按值传递
- 传递的是值的拷贝,也就是说传递后就互不相关了
- 如何取消按值传递:引用传递,其实传递的为引用的地址,也就是变量所对应的内存空间的地址。
- 什么是对象?
- 对象是数据类型的一个实例
- 每个实例都是类的一个对象
- 什么是面向对象编程?
- 是一种编程模式,将需用到的数据类型、方法定义为类,涉及数据封装、继承、多态等
- 本质:抽象出问题涉及的对象,设计一组抽象的类型,建模
- 结构类型是一种新的数据类型
- 数据隐藏:对象的属性应该在合理范围内,不允许直接访问,可通过成员函数间接访问
- 如何使用面向对象编程?
- 定义与问题相关的实体类型,根据问题解决方案确定每个类型的特性和操作。即抽象出类和方法的声明
- 编写类定义,对这些类型编码。即实现方法
- 根据对象,使用直接利用这些对象的操作编写解决问题的方案。即串联方案,解决问题
- 什么是类?
- 类是一种自己定义,用于描述对象,满足应用程序需求的数据类型,定义类用class,内聚某个问题所需的数据类型
- 类成员默认私有,可用访问指定符划定类成员显示区域:public、protected、private
- 类对象的大小一般是所有数据成员的大小总和,不包括静态数据成员的size
- 什么是封装?
- 封装就是用一个结构类型来描述对象属性和对象操作
- 什么是继承?
- 继承是一个类可以获得另一个类的特性的机制
- 继承是一种代码重用的形式,允许程序员基于现有类开发新类。现有类通常称为"基类"或"超类",新类通常称为"类"或"派生类"。
- 继承的好处:继承大的好处是代码的重用,与它同样重要的是它带来了多态(继承是实现多态的基础)
- 什么是多态?
- 不同时刻有不同形态,使用指针或引用调用对象成员函数。编译时未确定,执行时决定指向哪个成员函数
- 多态性好处:设计与编译时不能确认处理哪种类型的对象,只能在运行时确定(取决于用户的输入类型),而多态性可以满足这种需求,一般用于交互式应用程序
- 什么是构造函数?
- 所谓构造函数,就是与类同名的函数,它与普通函数的区别在于,它没有返回类型,也不会返回 void。
- 构造函数的作用:创建类对象时,为类成员赋初值与验证初值
- 如果类中定义了构造函数,则不能用初始化列表类初始化对象
- 默认构造函数,调用不指定参数列表,不用括号
- 什么是析构函数?
- 类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
- 析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。
- 析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
- 对象的释放顺序与创建它们的顺序相反,像栈一样,先进后出。
- 什么是副本?
- 拷贝机制,编译器会对所有入参制作临时副本
- 函数内对入参的操作均为对副本的操作
- 函数的参数,会对数组传地址,不会有副本机制,为了节约内存,数组传递的是指针
- 函数返回值有副本机制,返回的时候,另外再保存一份,当获取到返回值后,原来内存的数据就被销毁了
- 什么是副本构造函数?
- 一种特殊的构造函数,参数为类对象。用一个已创建的对象来初始化同类的另外一个对象,即对象copy
- 创建对象时,不用显示调用副本构造函数,只需将对象作为入参传入构造函数,编译器则会调用副本构造函数,创建对象副本。但只针对简单类
- 入参必须为引用,否则会递归call构造函数
- 入参必须用const修饰,因为副本构造函数仅创建副本,不修改原对象
- 缺点:两个对象的指针数据成员指向了同一块内存空间,可通过自已定义副本构造函数解决
- 如何禁止副本构造函数:声明为private,可以不实现
- 什么是内联函数?
- 类内定义的函数均为inline函数
- 函数声明在类内,但定义在类外的函数,看是否有inline修饰
- 一般函数的代码段只有一份,放在内存中的某个位置上,当程序调用它是,指令就跳转过来;当下一次程序调用它是,指令又跳转过来;而内联函数是程序中调用几次内联函数,内联函数的代码就会复制几份放在对应的位置上
- 内联函数的定义包含在.h头文件中,只有不是内联函数的定义才应放在.cpp文件中
- 什么是隐式类型转换?
- 隐式类型转换即偷偷把给定的类型转换为另外一种类型,不用显示强转。
- 对于类构造函数只有一个参数或只有一个无默认值入参,加上explicit表示显示转换,则可避免隐式转换
- 什么是友元?
- 在类定义中用friend声明友元函数、友元类
- 友元关系不能传递、不能反向
- 类外部的函数被指定为友元,则外部函数与类内部成员无异,可随意访问类内所有数据成员、成员函数
- 什么是this指针?
- 指向类实例对象地址的指针变量
- 返回类实例对象地址是需显示使用this指针变量
- 什么是引用?
- 引用即一个变量的别名,与目标变量占用同一片内存
- 引用即指针常量,指向的地址不改变
- 引用声明时必须初始化,初始化后不能修改值
- 写法:数据类型 &引用名 = 目标变量名;
- 数组不能引用,可以对数组单个变量进行引用
- 链表相对数组的优势?
- 链表长度不固定
- 链表可随意节点增删
- 两个方面:类成员的访问指定符、基类访问指定符,类成员与基类的默认访问指定符均为private
- private是自己私有的,protected是可以让孩子知道的,public是公开的!
- public:可以被任意实体访问
- protected:只允许子类及本类的成员函数访问
- private:只允许本类的成员函数访问。外部不能访问。获取私有数据成员的唯一方式是通过构造函数或成员函数
对象声明为const,只能调用被声明为const的成员函数,因为对象的this指针变量不能被修改
const只能应用于类的成员函数,函数指定为const则不能修改调用它的对象,const只能用于属于类的成员函数
const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性(没有真正去除)。
变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。
用法:const_cast(data)
- 无论类有多少个对象,静态数据成员只有一份,而非静态数据成员都是类中非静态数据成员的副本,每个对象有一份副本
- 即使未创建类的对象,类的静态数据成员依然存在
- 在类声明外部初始化静态数据成员,初始化时使用类名和作用域解析运算符限定成员
- 对象的数据成员包含此对象指针,可使对象链接起来,则将数据组织为结构、链表等
- 对象指针、对象引用作为函数参数,作为参数传递比直接传递效率更高,不用复制操作
- 开发容器类时,需仔细考虑该类的数据成员是否为源对象的副本
- 控制对类的访问:嵌套类
- 不能重载的运算符::: ?: . .* sizieof
- 确保标准运算符的重载版本与其原始用法含义基本保持一致
- 二元运算符‘X’重载:
- 写法:operator+‘‘需要重载的运算符’’,比如:bool operator<()
- 类成员函数:返回类型 operator X(类型 右操作数)
- 非成员函数:返回类型 operator X(类类型 左操作数,类型 右操作数)
- 非成员函数:返回类型 operator X(类型 左操作数,类类型 右操作数)
- 一元运算符’Op’重载:
- 类成员函数:类类型& operator Op()
- 全局函数:类类型& operator Op(类类型&)
- 派生类对象应代表有意义的基类对象,比如狗是一种动物,狗是有意义的、具体的,而动物无意义、不具体
- 三种测试:
- 种类测试:派生类应描述基类所表示对象的一个子集
- 基类是否有特性不能用于派生类?如果没有,继承就是可行的
- 没通过种类测试,则试下包含测试:类对象包含另一个类的实例,采用聚合
- 多重继承:派生类可以有任意多个直接基类,与单一继承相对(只使用一个基类)
- 虚基类,关键字virtual。为了避免同一基类的多个子对象被派生类多次包含,把重复的类声明为虚基类。
- 访问派生类的继承成员有两个因素控制:基类成员的访问指定符、派生类声明中基类的访问指定符
基类指针:基类指针可存储派生类对象地址,反过来不行,基类没有描述完整的派生类对象
什么是多态性:任何时刻,基类指针都可以指向任何派生于此基类的类对象。
“静态类型”:指针在声明时指向基类对象,通过静态解析的基类指针来调用函数,都会调用基类的函数。不取决于它指向的对象
“动态类型”:当指向派生类对象时,它会根据指向的对象类型而变化。
类描述为多态性,那么它是至少包含一个虚函数的派生类
多态性好处:
- 设计与编译时不能确认处理哪种类型的对象,只能在运行时确定(取决于用户的输入类型),而多态性可以满足这种需求,一般用于交互式应用程序
多态性的成本:
- 内存占用与程序文件更大,因为有vtable指针表
- 虚函数调用速度略慢,开销很小,可忽略
什么是虚函数:把一个函数声明为基类的虚函数,则派生于此基类的任何类中的此函数都是动态绑定的。用关键字virtual**声明(注意不是定义)**虚函数,虚函数是一个工具
- 使用对象或直接成员选择运算符调用虚函数-------静态解析,编译时解析
- 通过指针或引用调用虚函数---------动态解析,调用时解析
- 生效规则:如果派生类与基类中虚函数的函数名、参数列表、返回类型或者修饰符(比如const)不同,则虚函数机制失效,编译时固定为静态绑定。访问指定符不同不影响虚函数生效
- 模板函数不能为虚函数
- 虚函数默认值为编译时决定
纯虚函数
- 定义:基类虚函数只声明,不实现,在类的声明中加上“ = 0”(加在参数列表后)
抽象类
- 定义:包含纯虚函数的类称为抽象类
- 存在的意义:定义派生于它的其他类,不允许创建抽象类的实例
- 抽象属性可继承:派生类如果未定义抽象基类的纯虚函数,纯虚函数会原封不动地继承下来,则派生类也是一个抽象类
静态类型转换 static_cast
- static_cast比较接近于C语言中的强制转换,多用于不同的基本数据类型的转换
- 在编译期间转换,转换失败的话会抛出一个编译错误
- 用法:static_cast(data)
该运算符把data转换为newType类型,但没有运行时类型检查来保证转换的安全性 - 将派生类指针转换为基类指针是安全的;反之,将基类指针转换为派生类指针是不安全的
动态强制转换 dynamic_cast
用法:dynamic_cast(data)
dynamic_cast 会在程序运行期间借助 RTTI 进行类型转换,这就要求基类必须包含虚函数
newType 和 data 必须同时是指针类型或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、double、数组、类、结构体等)都不行。
对于指针,如果转换失败将返回 NULL;对于引用,如果转换失败将抛出
std::bad_cast
异常。
虚析构函数
- 如果基类包含虚函数,则基类的析构函数应声明为virtual
- 析构函数声明中增加virtual关键字,告知编译器,通过指针或引用调用的析构函数是动态绑定的,运行时动态选择
运行器件标识类型
- typeid 的操作对象既可以是表达式,也可以是数据类型
- 用法:
- typeid( dataType )
- typeid( expression )
- typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常引用
类成员指针
- 数据成员指针:
- 不是类对象的数据成员指针,而是类成员的指针。它只是在和Box类型对象一起使用时,才指向内存中的某个位置
- 在类包含相同类型的几个数据成员时,就可使用数据成员指针
- 成员指针选择运算符:
- 直接指针选择运算符:“.*” = 直接成员选择运算符“.” + 解除引用运算符"*"
- 间接指针选择运算符:“->*” = 间接成员选择运算符"->" + 解除引用运算符“*”
- 成员函数指针:
- 与函数指针类似。
- 注意调用运算符“()”的优先级高于选择运算符"->",所以必须在调用前给函数加上括号
- 为类class_type的函数声明一个指针写法:return_type (class_type::*pointer_name) (parameter_type_list);
- 声明函数指针同名词:typedef return_type(class_type::*ptr_typename)(parameter_type_list)
- 成员函数的参数可以是成员的指针
- 数据成员指针:
- 流:程序中输入或输出设备(数据的来源或目的地)的抽象表示。流是外部设备与计算机内存之间流动的一系列字节
- 数据传输模式:文本模式、二进制模式
- 流的读写操作:提取和插入运算符读写各种类型的数据、读写字符
- 三类工具:容器、迭代器、算法
- 序列容器:
- vector
- 适合尾部增删,类似数组
- size()
- capacity()
- deque
- 适合头尾增删,double-ended queue
- size()
- 无capacity函数,容器大小始终等于其容量
- list
- 适合中间增删,类似链表
- pPrev
- pNext
- vector
- 关联容器:
- map
- multimap
- set
- multiset
- map\set键值唯一
- multimap\multiset键值可重复
- map
- 迭代器
- 迭代器是一种智能指针
- 从容器中获得的迭代器特性取决于容器类型
- 算法
- 算法是STL中大的工具集合
- 算法有三大类:
- 不修改序列的操作
- 修改序列的操作
- 排序、合并和相关操作
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
本文名称:我对面向对象编程的一些理解-创新互联
网页URL:http://scjbc.cn/article/djcioc.html