zhouqijie

序章 自定义数据类型

概述

C++除了内置的基本数据类型,还允许自定义数据类型。
自定义数据类型有:枚举类型、结构体类型、联合类型、数组类型、类类型等。

变量的存储

程序运行时,所有变量的值都存储在内存中。内存中每一个单元都有一个唯一的编号,这个编号就是它的地址。不同内存单元地址互不相同,C++目标代码就是靠地址来区别不同变量。

typedef声明

————可以给一个已有的数据类型另外命名——————
※格式:typedef 已有类型名 新类型名表列;
※例如:typedef int num;
—————–可以用来定义指针类型——————————
※类型指针:typedef int *P; (实例化:P p = &变量名;)
※函数指针:typedef int (*Func)(int); (实例化:Func func = 函数名)





第一章 枚举类型(enum)

声明格式

enum 枚举类型名
{
	Item1,
	Item2,
	Item3
}

变量定义/调用格式

enum FormMethod method1 = GET;
//或者
FormMethod method1 = GET;

※C++中枚举类型中的每个元素,可以直接使用,不必通过”类型.元素”的方式调用。 ※C#中的元素要通过”类型.元素”方式调用。

  1. 枚举项可以被赋值数值。例如:enum 枚举类型名{Item1=111, Item2=222}。
  2. 枚举与整型可以互相转换,枚举转整型是隐式转换。





第二章 结构体和联合体

结构体

※结构体和类一样。他们的唯一区别是他们有不同的默认访问控制属性,结构体默认public 而类默认private,并且结构体兼容C语言。

联合体

※联合体是一组数据,它们共享一组内存单元。在这组数据中至多只有一个数据是生效有意义的。





第三章 类

概述

在面向对象程序设计(OOP)中,程序模块是由类构成的。类是逻辑上相关函数与数据的封装,它是对问题的抽象描述。

类的定义

※不用声明可访问性修饰符,除非用CLR编译。

class Student
{
	private:
	…
	public:
	…
}

public:公有成员。定义了类的外部接口。 ※protected:保护成员。本类和本类的派生类可访问。 ※private:私有成员。只有本类能访问。

构造函数与析构函数

构造函数在对象创建时自动调用。构造函数作用是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定状态。

※复制构造函数作用是使用一个已经存在的对象,去初始化同类的一个新对象。其形参是本类对象的引用。
※只有把对象用值传递时,才会调用复制构造函数,如果传递引用,则不会调用复制构造函数。

※以下情况时,复制构造函数被调用:

  1. 用类的一个对象去初始化另一个对象时。
  2. 类对象作为某个函数的参数,这个函数被调用,形实结合时。
  3. 函数返回值是类的对象,函数执行完返回调用者时。

析构函数实在对象生存期即将结束的时候被自动调用的,它用来完成删除前的一些清理工作。如果不声明析构函数,系统也会自动生成一个函数体为空的析构函数。

对象的实例化

※ 类是对象的类型,对象是类的实例。

Student stu;                    //(隐式创建)
Student stu(args);              //(隐式创建) (不能用于无参构造) (无参构造加括号会被编译器视作函数声明)
Student stu = Student;          //(显式创建)
Student stu = Student();        //(显式创建)
Student * stu = new Student();  //(创建堆对象指针)

※ 对象实例化也就是类类型变量的定义过程。

  1. 分配空间。(此时成员值为未定义状态)
  2. 值初始化为0。(如果是值初始化)
  3. 默认成员初始化。(C++11新特性)
  4. 成员初始化列表。
  5. 构造函数的函数体中给成员赋值。

类的成员函数

※成员函数的原型声明写在类体中。 ※C++类的成员函数的实现(函数体)要写在类定义外,并且实现时要用”::”指定类名称。只有定义隐式内联成员函数时可以把函数体写在类定义里面。

成员非静态成员函数后面加const修饰符表示该成员函数不允许修改所在类的成员,即隐含传入的this指针是const指针。

分为隐式和显式。隐式是把函数体直接写在类定义中。显式是在函数实现前用inline关键字。

成员函数的调用必须使用.操作符指出调用所针对的对象,称为目的对象。

mutable关键字用于声明类的成员变量,使其在const成员函数中也能被修改。通常,const成员函数保证不会修改对象的任何成员变量,但mutable成员是一个例外。引入mutable关键字的目的是为了在某些情况下提供灵活性。

this指针

this指针在成员函数内用来指向其调用者(一个对象)。

内部工作过程是,编译器自动将this指针加到每一个成员函数的参数列表。

CRE:通常是查到参数列表最前面。(例如void foo(XXX xxx);变为void foo(MyClass *this, XXX xxx)

静态类成员(Static Member)

静态(static)数据成员用来表示唯一的、可共享的成员。它可以在用一个类的所有对象中被访问。

这种定义看起来像全局对象的定义。唯一差别是其名称前面需要加上类作用域运算符。

一个成员函数,只有在“不访问任何非静态成员”的条件下才能被声明为static。

CRE:运算符的重载技巧

可以重载!=*++等运算符,来实现一个Iterator类。
可以重载()运算符,来实现一个函数对象(可调用对象)。
可以重载ostream<<来实现输出。

类的组合

※一个类把其他类的对象作为成员,称为类的组合
※是一种依赖关系。
※两个类相互引用,称为循环依赖

创建类的对象时,如果有内嵌对象成员,那么先按定义顺序调用内嵌对象的构造函数,再调用本类的构造函数。析构函数的调用顺序正好和构造函数相反。

格式: 类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表)
例如: Line::Line(Point _p1, Point _p2) : p1(_p1), p2(_p2)

前向引用声明

※C++的类必须先定义再使用。

※如果遇到需要在类的定义前面引用类名的情况 (例如循环依赖),可以用前向引用声明。]他可以把类的名字告诉编译器,使编译器知道那是一个类名。