C++面向对象程序设计学习笔记(3)
类与对象(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)的更多相关文章
- C++面向对象程序设计学习笔记(1)
基本概念 对象: 面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体,每个对象都是由数据和操作代码两部分构成的. 类: 面向对象程序设计中,类是具有相同的数据 ...
- C++面向对象程序设计学习笔记(6)
多态性 编译时的多态性与运行时的多态性 在面向对象方法中,所谓多态性就是不同对象收到相同信息时,产生不同的行为.在c++程序设计中,即"一个接口,多种方法" 在C++中,多态性的实 ...
- C++面向对象程序设计学习笔记(7)
模板与异常处理 模板的概念 模板是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型作为参数. 模板分为函数模板和类模板,它们分别允许用户构造模板类和模板函数 函数模板与模板函数 函数模板实际 ...
- C++面向对象程序设计学习笔记(5)
派生类与继承 概念 继承允许编程者在已有类的基础上创建新的类,可以从一个或者多个已有类中继承函数和数据,并重新定义或者添加新的函数和数据,已有类称为基类或父类,新类称为派生类和子类. 声明 声明一个派 ...
- C++面向对象程序设计学习笔记(4)
类与对象(2) string类 C++不仅向下兼容C的字符表示方法,也声明了一种更方便的字符串类型,即string类. 想要使用string类,必须包括头文件string,即要声明 #include& ...
- C++面向对象程序设计学习笔记(2)
C++在非面向对象方面的扩充 C++向下兼容C语言,因此C语言中的语法在C++中依然成立 输入输出 C++添加了标准输入流对象cin和标准输出流对象cout来进行输入输出, 例: #include&l ...
- 20145213《Java程序设计学习笔记》第六周学习总结
20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...
- Java程序设计学习笔记(一)
时间:2015-6-2 23:04 程序员,程序猿,程序媛,码农 ------------------------------------------------------- --Java的应用 ...
- JavaScript高级程序设计---学习笔记(二)
面向对象程序设计1.属性类型.定义多属性.读取属性特性对象的属性在创建时都带有一些特征值,JavaScript通过这些特征值来定义它们的行为.这些特性是为了实现JavaScript引擎用的,因此不能直 ...
随机推荐
- 【2019.7.24 NOIP模拟赛 T1】道路建设(road)(水题)
原题与此题 原题是一道神仙不可做题,两者区别在于,原题不能有重边和自环. 然而,这题可以有重边... 于是这题就变成了一道大水题. 此题的解法 考虑如何构造. 对于\(n\le10^4\)的情况: 对 ...
- ORB-SLAM2 地图保存
一.简介 在ORB-SLAM2的System.h文件中,有这样一句话:// TODO: Save/Load functions,让读者自己实现地图的保存与加载功能.其实在应用过程中很多场合同样需要先保 ...
- 5个你可能不知道的html5语义化标签
1.<ruby>:该标签作用为注释(中文注音或字符),比如可实现下面样式 详见:https://www.w3cschool.cn/html5/html5-ruby.html 2.< ...
- Ubuntu 16.04上源码编译和安装pytorch教程,并编写C++ Demo CMakeLists.txt | tutorial to compile and use pytorch on ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/54e7a3d8/,欢迎阅读最新内容! tutorial to compile and use pytorch on ubuntu ...
- Nginx Cache-Control
转自:https://www.cnblogs.com/sfnz/p/5383647.html HTTP协议的Cache-Control指定请求和响应遵循的缓存机制.在请求消息或响应消息中设置 Cach ...
- ubuntu18.04.2下编译openjdk9源码
最近在看<深入理解Java虚拟机 第二版>这本书,上面有关于自己编译OpenJDK源码的内容.自己根据书里的指示去操作,花了三天的时间,重装了好几次Ubuntu(还不知道快照这个功能,好傻 ...
- A query was run and no Result Maps were found for the Mapped Statement
mybatis测试方法报错: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exec ...
- Asp.NET Core Nginx Ocelot ForwardedHeaders X-Forwarded-For
ocelot在部署时我使用了nginx作为转发,并配置了https证书,但是发现ocelot不支持Forward host header. https://ocelot.readthedocs.io/ ...
- SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc
1.SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc报错. -java ...
- PHP实现简单RPC
1.什么是rpc RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”.目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用 ...