类与对象(1)

结构体与类

结构体的扩充

C++对结构体进行了扩充,它不仅可以含有不同类型的数据,还可以含有函数,结构体的函数可以像访问结构体中的数据一样进行访问。

类的声明

声明类的方法与声明结构体的方法相似,它是一种用户定义的抽象的数据类型。类是对象的抽象,而对象是类的实例。

C++为了保护类中数据的安全,将类中的成员分为两类,私有成员(private)和公有成员(public)。私有成员只能被类内的成员函数访问,不能被类外的对象访问,公有成员既能被类内的成员函数访问,也能被类外的对象访问。

类声明的一般形式如下:

class 类名
{
[privat:]
私有数据成员和成员函数
[public:]
公有数据成员和成员函数
};

在类的声明中,若不对其成员作private或public声明,系统将其默认为私有的,类声明中还有一种protected,称为保护成员,保护成员能被类内的成员函数访问,也能被本类的派生类的成员函数访问,但不能被类外的对象访问。

类声明中三种关键字都可以按任意次序出现任意次,数据成员可以是任意数据成员,但不能用auto,register或extern进行说明。

成员函数的定义

成员函数的用法与普通函数基本是一样的,只是它属于一个类的成员,可以访问本类中的任何一个成员,其类的声明也与前文一致。

成员函数的有三种定义方式:

(1)在类声明中只给出成员函数的原型,而将成员函数的定义放在类的外部,在类外定义的一般形式是:

返回值类型 类名 ::成员函数名(参数表)
{
函数体
}

(2)将成员函数直接定义在类的内部。

此时C++编译器会将函数作为内联函数执行(隐式定义)。

(3)在类定义中只给出成员函数的原型,而将成员函数的定义放在类的外部,在类内函数原型声明前或在类外定义成员函数前冠以关键字inline(显式定义)。

对象的定义及使用

对象的定义:

(1)声明类的同时,直接定义对象,即在花括号后添加对象名表。

(2)声明类之后,使用时再定义对象,一般形式如下:

    类名 对象名1,对象名2......

对象中成员的访问:

(1)通过对象名和对象选择符访问对象中的成员:

一般形式

对象名.数据成员名
对象名.成员函数名[(实参表)]

(2)通过指向对象的指针访问对象中的成员:

对指针应该使用“->”操作符

(3)通过对象的引用来访问:

与对象选择符方法相同

类的作用域和类的访问属性

公有成员不但可以被类中的成员函数访问,还可以在类外通过对象访问。

私有成员只能被类中的成员函数访问。

构造函数和析构函数

对象的初始化和构造函数

类是一种抽象的数据类型,因此不能在声明中为数据成员赋初值。

如果类中的所有成员都是公有的,则可以在定义对象时对数据成员进行初始化,如:

class Complex{
public:
double real;
double imag;
};
Complex c={1.1,2.2};

若类中包含私有或保护的成员,则不能用这种方法进行初始化。可用公有的成员函数对对象中的数据成员赋值,也可以使用构造函数进行赋值。

构造函数是一种特殊的成员函数,主要用于为对象分配空间,进行初始化。构造函数的名字必须与类名相同,不需要用户来调用,而是建立对象时自动执行的。

采用构造函数为对象赋值,主要有以下两种形式:

(1):
类名 对象名[(实参表)];
(2)
类名 *指针变量名 =new 类名 [(实参表)];

如果没有给类定义构造函数,则编译系统自动的生成一个默认的构造函数。该默认构造函数不带任何参数,只能为对象开辟数据成员储存空间,而不能给对象中的数据成员赋初值。

构造函数可以不带参数。

用成员初始化列表对数据成员初始化

一般形式如下:

类名 ::构造函数名([参数名])[:(成员初始化列表)]
{
//构造函数体
}

成员初始化列表一般形式如下:

数据成员名1(初始值1),数据成员名2(初始值2),......

注意:对于使用const修饰的数据成员,或者是引用类型的数据成员,是不允许用赋值语句直接赋值的,因此只能用成员初始化列表对其进行初始化。

数据成员按照它们在类中的声明顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关。

例:

class tmp
{
private:
int a,b;
public:
tmp(int t):b(t),a(b+1){}
void show()
{
cout<<a<<' '<<b<<endl;
}
}; int main()
{
tmp t(1);
t.show();
return 0;
}

结果为:

28 1

构造函数的重载

C++允许构造函数重载。

注意:

(1)说明无参构造函数创建对象时,应使用语句"类名 对象名;",而不是"类名 对象名();"因为该声明表示一个名为对象名的普通函数。

(2)如果类中用户没有定义构造函数,则系统会自动提供一个函数体为空的默认构造函数,但只要定义了一个构造函数,则不会提供默认构造函数。

(3)对于一个对象,建立一个对象只执行其中一个构造函数。

带默认参数的构造函数

C++允许构造函数带默认参数。

注意:

(1)如果构造函数在类的声明中定义,那么默认参数应该在类中声明构造函数原型时指定,而不能在类外构造函数定义时指定,目的是为了让用户知道如何使用默认参数。

(2)如果构造函数的全部参数都指定了默认参数,那此时构造函数也属于默认构造函数,不能再同时声明无参数的默认构造函数,因为会产生二义性。

析构函数

析构函数执行与构造函数相反的任务,通常用于执行一些清理任务。

特点:

(1)函数名与类名相同,但需要在前面加'~'。

(2)不返回任何值,也不能说明类型。

(3)没有参数,因此不能被重载。

(4)撤销对象时,自动调用析构函数。

注意:

(1)每个类必须有一个析构函数,若没有显式定义一个析构函数,则会自动生成一个默认析构函数,它能完成大部分的处理任务。

(2)除了在主函数结束(或调用exit()函数)时,系统会调用析构函数外,以下情况下也会调用:

①对象被定义在函数体中,函数调用结束后,将调用析构函数。

②使用new运算符建立的对象,如用delete运算符释放时,将调用析构函数。

对象数组与对象指针

对象数组

定义对象数组与定义正常的数组的方式相似,建立一个对象数组的格式如下:

类名 数组名[下标表达式]

如果构造函数只有一个参数,则可直接在等号后的花括号中提供实参。

对象数组的元素访问与正常数组的访问方式相似,一般形式是:

数组名[下标].成员名

若构造函数有多个参数,则可通过指定实参的构造函数定义对象数组:

tmp a[3]={
tmp(1,2,3),
tmp(2,3,4),
tmp(3,4,5)
};

对象指针

定义对象指针与定义正常的指针的方式相似,例:

类名 * 对象指针名

可以通过'.'运算符来访问单个对象的成员,也可通过'->'运算符来通过指针访问对象

this指针

因为C++将函数代码储存于对象空间之外,所以C++为成员函数提供一个名为this的指针,称为自引用指针,成员函数引用数据成员时,按照this指针找到对象的数据成员。this指针是隐式使用的,它作为参数传递给成员函数。

C++面向对象程序设计学习笔记(3)的更多相关文章

  1. C++面向对象程序设计学习笔记(1)

    基本概念 对象: 面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体,每个对象都是由数据和操作代码两部分构成的. 类: 面向对象程序设计中,类是具有相同的数据 ...

  2. C++面向对象程序设计学习笔记(6)

    多态性 编译时的多态性与运行时的多态性 在面向对象方法中,所谓多态性就是不同对象收到相同信息时,产生不同的行为.在c++程序设计中,即"一个接口,多种方法" 在C++中,多态性的实 ...

  3. C++面向对象程序设计学习笔记(7)

    模板与异常处理 模板的概念 模板是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型作为参数. 模板分为函数模板和类模板,它们分别允许用户构造模板类和模板函数 函数模板与模板函数 函数模板实际 ...

  4. C++面向对象程序设计学习笔记(5)

    派生类与继承 概念 继承允许编程者在已有类的基础上创建新的类,可以从一个或者多个已有类中继承函数和数据,并重新定义或者添加新的函数和数据,已有类称为基类或父类,新类称为派生类和子类. 声明 声明一个派 ...

  5. C++面向对象程序设计学习笔记(4)

    类与对象(2) string类 C++不仅向下兼容C的字符表示方法,也声明了一种更方便的字符串类型,即string类. 想要使用string类,必须包括头文件string,即要声明 #include& ...

  6. C++面向对象程序设计学习笔记(2)

    C++在非面向对象方面的扩充 C++向下兼容C语言,因此C语言中的语法在C++中依然成立 输入输出 C++添加了标准输入流对象cin和标准输出流对象cout来进行输入输出, 例: #include&l ...

  7. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  8. Java程序设计学习笔记(一)

    时间:2015-6-2 23:04 程序员,程序猿,程序媛,码农 -------------------------------------------------------   --Java的应用 ...

  9. JavaScript高级程序设计---学习笔记(二)

    面向对象程序设计1.属性类型.定义多属性.读取属性特性对象的属性在创建时都带有一些特征值,JavaScript通过这些特征值来定义它们的行为.这些特性是为了实现JavaScript引擎用的,因此不能直 ...

随机推荐

  1. 第04组 Alpha冲刺(4/6)

    队名:new game 组长博客:戳 作业博客:戳 组员情况 鲍子涵(队长) 燃尽图 过去两天完成了哪些任务 才两天,也就是实现一些功能而已 复习 接下来的计划 实现更多的功能 为这周的比赛准备 还剩 ...

  2. docker 通过中间镜像加速部署

    概要 实施 修改前的实施时间 制作编译用的镜像 测试修改后的实施时间 概要 使用 docker 打包镜像的时候, 每次耗费时间最多的就是 docker build 的过程. 特别是对于前端工程的打包, ...

  3. 原生js实现append()方法

    一.在使用jquery时,append() 方法在被选元素的结尾(仍然在内部)插入指定内容 使用方法:$(selector).append(content),content为必需的.规定要插入的内容( ...

  4. 我的周记13——”离开,是为了更好的回来"

    一点分享 生存是一种即时策略游戏,所有的人都是这场游戏的玩家.财务自由了,就是游戏赢家. 具体来说,又分成两种游戏:财富游戏和地位游戏.财富游戏的玩家追求更多的财富,地位游戏的玩家追求更高的地位. 古 ...

  5. skeleton在心意web上的实践

    通过手动编写skeleton,在fetch数据时显示skeleton loading,数据拉取成功隐藏skeleton 先看下效果图 在component下创建页面对应的skeleton,然后通过在i ...

  6. Flask restful源码分析

    Flask restful的代码量不大,功能比较简单 参见 http://note.youdao.com/noteshare?id=4ef343068763a56a10a2ada59a019484

  7. NumPy 文件数据读写

    写数据 NumPy 数组可以使用 np.save 方法保存到本地磁盘中,默认扩展名是 .npy,并且是未压缩的二进制格式. import numpy as np a = np.array([[0, 1 ...

  8. 【WPF入门视频】Microsoft ToDo 应用项目实战

    项目实战视频地址 第一天 第二天 第三天 第四天 第五天 第六天 项目实战源代码下载地址: 项目源代码下载

  9. C 储存类与运算符

    储存类 参考链接:https://www.runoob.com/cprogramming/c-storage-classes.html 存储类定义 C 程序中变量/函数的范围(可见性)和生命周期 au ...

  10. 今日头条3面,被泄露的Java最新面试题

    一.面试第 1 轮 1. linux 网络模型 2. b+树 3. 阻塞队列 4. redis 和 MongoDB 的区别.几个概念对比,还有底层实现. 5. 算法题: merge k sorted ...