类与对象(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. MyBatis 构造动态 SQL 语句

    以前看过一个本书叫<深入浅出 MFC >,台湾 C++ 大师写的一本书.在该书中写到这样一句话,“勿在浮沙筑高台”,这句话写的的确对啊.编程很多语言虽然相通,但是真正做还是需要认真的学习, ...

  2. redis之GeoHash

    Redis 提供的 Geo 指令只有 6 个,它只是一个普通的 zset 结构. 增加geoadd 指令携带集合名称以及多个经纬度名称三元组,注意这里可以加入多个三元组127.0.0.1:6379&g ...

  3. python小项目(python实现鉴黄)源码

    import sys import os import _io from collections import namedtuple from PIL import Image class Nude( ...

  4. date——系统时间的命令

    这是一个可以用各种姿势获得各种时间的命令.最近在写自动化定时脚本时学了一下. 参考:https://www.cnblogs.com/ginvip/p/6357378.html 比如: 利用cronta ...

  5. MongoDB官方下载安装设置配置文件指定端口号

    1.)下载 官网(https://www.mongodb.com/)右上角try free  进入下载中心,下载指定版本 ZIP和MSI随便 如果浏览器下载的慢,可以直接使用下载地址,然后迅雷下 操作 ...

  6. Nginx自建SSL证书部署HTTPS网站

    一.创建SSL相关证书 1.安装Nginx(这里为了测试使用yum安装,实际看具体情况) [root@localhost ~]# yum install nginx -y #默认yum安装已经支持SS ...

  7. 【洛谷5438】【XR-2】记忆(数论)

    [洛谷5438][XR-2]记忆(数论) 题面 洛谷 题解 很好的一道题目. 我们首先把所有数的每个质因子的出现次数模二,也就是把最大的完全平方因子给除掉.然后剩下部分一样的就可以产生\(1\)的贡献 ...

  8. Java 函数式编程—@FunctionalInterface----functional interface

    单一函数接口,可以使用拉姆达表达式的形式具体化和实例化. 本质是将接口函数签名化. 如定义了一个函数式接口如下: @FunctionalInterface interface GreetingServ ...

  9. 锁定文件失败,打不开磁盘“D:\biehl\centos\taotao\taotao-dubbo-register\CentOS-000001.vmdk”或它所依赖的某个快照磁盘。模块“Disk”启动失败。未能启动虚拟机

    1.锁定文件失败,打不开磁盘“D:\biehl\centos\taotao\taotao-dubbo-register\CentOS-000001.vmdk”或它所依赖的某个快照磁盘.模块“Disk” ...

  10. Python - 元组 - 第九天

    Python 元组 Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可.例如: >&g ...