C++:清华大学《C++面向对象程序设计》课程笔记(上)—基础语法

C++:清华大学《C++面向对象程序设计》课程笔记(上)—基础语法

本文主要记录了清华大学《C++面向对象程序设计》课程的基础语法笔记,使用的语法规则基于“std::C++11”版本,编译环境为Dev-C++ 5.11,供读者阅读学习或者收藏,转载须经本人许可。

【变量定义与初始化】

【main函数的命令行参数】

采用命令行导入参数,使用atio()模块:

1.argv为传入的字符串数组,可用来输入参数,通过命令行设置参数执行代码程序。

2auto 自动赋予变量类型

在这里插入图片描述

【指针变量的动态生成与删除】

1.指针变量所指内存可以通过new/delete运算符在程序运行时动态生成和删除

在这里插入图片描述

这里需要注意的是int* b=new int(10);b是单个指针变量,以及未被赋值的ptr在内存中被分配为随机地址。

【左值引用】

1.形如:类型名&引用名=变量名,引用必须在定义时初始化(赋初值),被引用的变量名可以是结构体变量成员

在这里插入图片描述

函数参数采用引用类型,表示函数的形参与实参是同一变量,改变形参将改变实参。

2.此外,函数返回值可以是引用类型,但返回的引用不可以是该函数的局部临时变量。

在这里插入图片描述

这里需要注意的是swap(int &x,int &y)的写法,swap(int& x,int& y)也表示引用类型。

【右值引用】

1.形如:类型名&&引用名 表达式(右值:无法取地址以及变量名称的值或表达式)

例如:int&&sum=3+4;float&& res=ReturnType(f1,f2);

在这里插入图片描述

2.右值引用的典型应用是在函数参数中,Void AcceptedValueRef(T&& s){…};

3.目的是:减少临时变量拷贝的开销。

【 初始化列表】

1.用花括号{}包括的元素序列,用来对变量进行初始化:

在这里插入图片描述

【变量的类型推导】

1.decltype可以对变量或表达式结果的类型进行推导,追踪参考数据的类型

在这里插入图片描述

【基于范围的for循环语句】

基于范围的for循环:在循环头部的圆括号中,由冒号“:”分为两部分,第一部分是用于迭代的变量,第二部分则表示将被迭代的范围

在这里插入图片描述

【自定义类class】

【在类外定义成员函数】

1.形如:返回类型 类名::函数名( ){…},用于在自定义类外部进行成员函数的定义。

在这里插入图片描述

【友元函数】

1.有时需要允许外部函数访问对象的私有成员,可以通过声明该函数为需要访问的类的“友元”来实现。

在这里插入图片描述

这里需要注意的是**在class内部对外部函数fill( )的声明格式,为“friend+返回值类型 函数名(类名 形参对象)”**,而原来的函数头部不需要发生任何改变,这点与类外定义成员函数的方法易混淆。

【构造函数】

1.类的构造函数由编译器自动生成调用语句,用于对象数据成员的初始化。

2.构造函数没有返回值类型,函数名与类名相同。类的构造函数可以重载,用于使用不同的函数参数进行对象初始化。

3.在定义元素为对象数组(ClassName array_var[10];)时,类必须提供构造函数的定义

4.使用默认构造函数(没有参数)来生成对象时,对象定义的格式为:ClassName obj;而不能使用ClassName obj()。

【构造函数的初始化列表】

1.构造函数可以使用初始化列表初始化成员数据,而该列表在定义构造函数时使用,使用“数据成员(初始值)”的形式。

在这里插入图片描述

需要注意的是初始化列表实参传入的格式,实则先将外部的实参传入构造函数的形参,再通过列表初始化将这些入的实参赋值给内部的私有成员变量

【析构函数】

1.一个类只有一个析构函数,名称是“~类名”,且无函数返回值和函数参数。编译器在对象生命期结束时自动调用类的析构函数,以便释放对象的资源。

在这里插入图片描述

需要注意的是这里的delete并非指简单把指针Id_list赋值为空,而是把整个指针删除。

【拷贝构造函数】

1.函数调用时以类的对象为形参或返回对象时,编译器会自动调用“拷贝构造函数”,在已有对象的基础上生成新的对象

2.拷贝构造函数是一种特殊的构造函数,它的参数是语言规定的,是同类对象的常量引用。

在这里插入图片描述

当需要传入对象参数时,会自动调用拷贝构造函数;生成新的对象时调用的是构造函数,有所区分。

【赋值运算符重载】

1.赋值运算符函数是在类中定义的特殊成员函数。

在这里插入图片描述

注意这里:基类this使用“->”,而传入的对象类right使用“.”。

【流运算符(>>和<<)的重载】

1.函数名为:operator>>和operator<<,返回值为:istream&和ostream&,均为引用。形式参数分别为:流对象的引用、目标对象的引用。

在这里插入图片描述

【函数运算符()的重载】

1.函数运算符()也能重载,它使对象看上去是一个函数名。

在这里插入图片描述

这里需要注意调用的方式,是类对象名(传入的参数),而不是通过成员函数的调用方式类对象.(传入的参数)

【数组下标运算符[]重载】

1.函数的声明形式:返回类型 operator[] (){…};

2.如果返回类型是引用,则数组运算符调用可以出现在等号左边,接受赋值,即:Obj[index]=value;如果返回类型不是引用,则只能出现在等号右边:Var=Obj[index]

在这里插入图片描述

【重载前缀++/–和后缀++/–】

1.前缀运算符重载声明:ReturnType operator++( )和ReturnType operator–();

2.后缀运算符重载声明:ReturnType operator++(int dummy)和ReturnType operator–(int dummy)。

【静态成员】

1.在类型前面加上static修饰的数据成员,是隶属于类的,称为类的静态数据成员,也称“类变量”。

2.静态数据成员被该类的所有对象共享(即所有对象的这个数据域实际上处于同一内存位置),静态数据要在实现文件中赋初值,格式为:Type ClassName::static_var=Value。

3.返回值类型前面加上static修饰的成员函数,称为静态成员函数,它们不能调用非静态成员函数

4.类的静态成员(数据、函数)既可以通过对象来访问,可以通过类名来访问。

在这里插入图片描述

【类中的常量成员】

1.使用const修饰的数据成员,称为类的常量数据成员,在对象的整个生命周期里不可更改

2.常量数据成员只能在构造函数的初始化列表中设置,不允许在函数体中通过赋值来设置

3.若用const修饰成员函数,则该成员函数在实现时不能修改类的数据成员。

4.若对象被定义为常量,则它只能调用以const修饰的成员函数,其他普通成员函数不允许调用

在这里插入图片描述

【类的组合】

1.可以在类中使用其他类来定义数据成员,通常称之为“子对象”,而这种包含与被包含对象间的关系称为“组合”,而组合关系是可以嵌套的。

2.子对象构造时若需要参数,则应在当前类的构造函数的初始化列表中进行赋值;若使用默认构造函数来构造子对象,则不做任何处理

在这里插入图片描述

3.对象的构造和析构次序:先完成子对象的构造,再完成当前对象的构造;而析构时,先完成对当前对象的析构,再完成对子对象的析构。

【移动构造函数】

语法:ClassName(ClassName&&);

目的:1.用来偷取“临时变量”中的资源(如内存)。

​ 2.临时变量被编译器设置为常量形式,使用“拷贝构造”函数无法将资源“偷”出来。(这里的“偷”是对原对象的一种改动,违反常量的限制。)

​ 3.基于 “右值引用”定义的“移动构造”函数支持接受临时变量,能“偷”出变量中的资源!

在这里插入图片描述

【类的继承与派生】

【继承方式】

1.在已用类的基础上,可以通过“继承”来定义新的类,实现对已有代码的复用。

2.常见的继承方式:public,private。

class Derived:[private]Base{…};缺省继承方式为private继承。

class Derived:public Base{…}。

3.被继承的已有类,称为基类(base class),也称“父类”;而通过继承得到的新类,被称为派生类(derived class),也称“子类/扩展类”。

【派生类对象的构造与析构过程】

1.目的:基类中的数据成员,通过继承成为派生类对象的一部分,需要在构造派生类对象的过程中调用基类构造函数来正确初始化。

2.若没有显示调用,则编译器会自动生成一个对基类的默认构造函数的调用;若采用显示调用,则只能在派生类构造函数的初始化成员列表中进行,既可以调用基类中不带参数的默认构造函数,也可以调用合适的带参数的其他构造函数。

3.先执行基类的构造函数来初始化继承来的数据,再执行派生类的构造函数;对象析构时,先执行派生类析构函数,再执行由编译器自动调用的基类的构造函数。

【继承基类构造函数】

1.在派生类中使用using Base::Base;来继承基类构造函数,相当于派生类“定义”了相应参数的构造函数。

在这里插入图片描述

2.虽然基类构造函数的参数默认值不会被派生类继承,但由默认参数导致的多个构造函数版本都会被派生类继承。

3.如果基类的某个构造函数被声明为私有成员函数,则不能再派生类中声明继承该构造函数。

4.如果派生类使用了继承基类构造函数,编译器就不会再为派生类生成默认构造函数。

【派生类(对象)中的基类成员】

1.派生类对象包含从基类继承来的数据成员,构成“基类子对象”。

2.基类中的私有成员,不允许在派生类成员函数中被访问,也不允许派生类的对象访问他们。(真正体现“基类私有”,对派生类也不开放其权限!)

3.基类中的公有成员:

若是使用public继承方式,则成为派生类的公有成员,既可以在派生类成员函数中访问,也可以被派生类的对象访问。

若是使用private继承方式,则只能提供给派生类成员函数访问,不能被派生类的对象访问。

【派生类重写基类成员函数】

1.基类已被定义的成员函数,在派生类中可以重新定义它,这被称为“函数重写”(override)。

2.重写发生时,基类中该成员函数的其他重载函数都将被屏蔽掉,不能提供给派生类对象使用

在这里插入图片描述

3.在派生类中使用using类名::成员函数名;在派生类中“恢复”指定的基类成员函数(即去掉屏蔽),使之重新可用。

在这里插入图片描述

【向上映射与向下映射】

1.派生类对象转换成基类对象,称为向上映射。而基类对象转换成派生类对象,则称为向下映射。

2.向上映射(派生类到基类的映射)可以由编译器自动完成,是一种隐式的自动类型转换。

在这里插入图片描述

3.凡是接受基类对象的地方(如函数参数),都可以使用派生类对象,编译器会自动将派生类对象转换为基类对象以便使用。

【虚函数】

1.对于被派生类重写的成员函数,若它在基类中被声明为虚函数(如下所示),则通过基类指针或引用调用调用该成员函数时,编译器将根据所指(或引用)对象的实际类型决定是调用基类中的函数,还是调用派生类重写的函数。

在这里插入图片描述

2.若某成员函数在基类中声明为虚函数,当派生类重写它时,无论是否声明为虚函数,该成员函数都仍然是虚函数。

【禁止重写的虚函数】

1.使用final关键字修饰的虚函数,派生类不可对它进行重写(即不可以改变函数的定义)。

2.在派生过程中,final可以在继承关系链的“中途”进行设定,禁止后续派生类对指定虚函数重写

在这里插入图片描述

【类之间的类型转换】

【自定义类型转换】

方法一:在源类中定义“目标类型转换运算符”。

在这里插入图片描述

方法二:在目标类中定义“源类对象作参数的构造函数”。

在这里插入图片描述

【自动类型转换(隐式转换)】

在调用对象传入实参时,会发生自动类型转换,如下:

在这里插入图片描述

【禁止自动类型转换—explicit/delete】

方法一:在自定义类型转换函数的前面,添加“explicit”,用于禁止自动类型转换:

在这里插入图片描述

方法二:使用=delete修饰的成员函数,不允许被调用:

在这里插入图片描述

【强制类型转换(显式转换)】

1.dynamic_cast<Dst_Type>(Src_var):

1.1:Src_var必须是引用或指针类型,Dst_Type类中含有虚函数,否则会有编译错误。

1.2:若源类没有继承目标类,则转换失败,返回空指针(注:转换失败并不是运行崩溃)。

2.static_cast<Dst_Type>(Src_var):

2.1:基类对象不能转换成派生类对象,但基类指针可以转换成派生类指针

2.2:派生类对象(指针)可以转换成基类对象(指针)。

2.3:没有继承关系的类之间,必须具有转换途径才能进行转换(要么自定义,要么是语言语法支持)。

在这里插入图片描述

【函数模板,类模板,成员函数模板】

【函数模板】

有些算法实现与类型无关,所以可以将函数的参数类型也定义为一种特殊的“参数”,这样便可得到“函数模板”。

定义函数模板的方法:

template

返回类型 函数名称(函数参数);

在这里插入图片描述

函数模板的完全特化示例:

在这里插入图片描述

【类模板】

1.在定义类时也可以将一些类型信息抽取出来,用模板参数来替换,从而使类更具有通用性。这种类称为“类模板”:

方法一,在类模板中定义:

在这里插入图片描述

方法二,在类模板外定义:

在这里插入图片描述

2.类模板的“模板参数”

类型参数:使用typename或class标记。

非类型参数:整数,枚举,指针(指针对象或函数),引用(引用对象或引用函数)。

在这里插入图片描述

【成员函数模板】

普通类的成员函数,也可以定义为函数模板。

方法一,在类内定义:

在这里插入图片描述

方法二,在类外定义:

在这里插入图片描述

【类模板的部分特化】

对于类模板,允许部分特化,即部分限制模板的通用性:

在这里插入图片描述

若指定所有类型,则<>内将为空:

在这里插入图片描述

普通的函数模板特化,完全特化的类模板示例:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/acceptedday/article/details/106267023