一、类的介绍
类是属于用户自定义的数据类型, 并且该类型的数据具有一定的行为能力, 也就是类中说描述的方法。通常来说, 一个类的定义包含两部分的内容, 一是该类的属性, 另一部分是它所拥有的方法。
二、类
1、类声明:
class Date;
在声明之后,定义之前,只知道Date是一个类名,但不知道包含哪些成员。只能以有限方式使用它,不能定义该类型的对象,只能用于定义指向该类型的指针或引用,声明(不是定义)使用该类型作为形参类型或返回类型的函数。
void Test1(Date& a){};
void Test1(Date* a){};
2、类定义
在创建类的对象之前,必须完整的定义该类,而不只是声明类。所以,类不能具有自身类型的数据成员,但可以包含指向本类的指针或引用。
class xx//xx为类名
{
public:
//公共属性或行为
private:
//私有的属性或行为,
};
//一般将类的数据成员设为私有的,以实现隐藏和封装
而将类的成员方法设为公有的
①. 类名 需要遵循一般的命名规则(驼峰式命名);
②. public 与 private 为属性/方法限制的关键字, private 表示该部分内容是私密的, 不能被外部所访问或调用, 只能被本类内部访问; 而 public 表示公开的属性和方法, 外界可以直接访问或者调用。
一般来说类的属性成员都应设置为private, public只留给那些被外界用来调用的函数接口, 但这并非是强制规定, 可以根据需要进行调整;
③. 结束部分的分号不能省略。
注:类的成员默认是私有的,而结构体的成员默认是公有的。
3、隐含的this指针
成员函数具有一个附加的隐含形参,即 this指针,它由编译器隐含地定义。成员函数的函数体可以显式使用 this 指针。
4、使用this指针
当我们需要将一个对象作为整体引用而不是引用对象的一个成员时。最常见的情况是在这样的函数中使用 this:该函数返回对调用该函数的对象的引用。
三、构造函数
- 构造函数的名字与类名相同,没有返回类型,一个类可以通过函数重载定多个构造函数,构造函数的参数列表中含有一个或多个需要进行初始化的数据成员。
Date:: Date(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
或者这样定义
Date:: Date(int y,int m,int d):year(y),month(m),day(d){}//参数列表的形式
2.默认构造函数
默认构造函数是在未提供初始值时进行对象初始化的构造函数。
当一个类没有提供任何的构造函数时,编译器会隐式地定义一个默认构造函数。以Date类为例,编译器提供的默认构造函数的形式应该是如下的
Date() {};
当构造函数中所有的参数都有默认值时,这个构造函数也是默认构造函数。例如:
Date:: Date(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
但是,当显式地定义了构造函数后,编译器便不会再提供默认构造函数。
-
构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。初始化列表属于初始化阶段(1),构造函数函数体中的所有语句属于计算阶段(2)
-
初始化列表比构造函数体先执行。不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。
-
const 对象或引用类型的对象,可以初始化,但不能对它们赋值,而且在开始执行构造函数的函数体之前要完成初始化。
初始化 const 或引用类型数据成员的唯一机会是构造函数初始化列表中,在构造函数函数体中对它们赋值不起作用。
没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,必须在初始化列表中完成初始化。
3、成员初始化的顺序
每个成员在构造函数初始化列表中只能指定一次。重复初始化,编译器一般会有提示。
成员被初始化的次序就是定义成员的次序,跟初始化列表中的顺序无关。
4、类对象的成员的初始化
在类A的构造函数初始化列表中没有显式提及的每个成员,使用与初始化变量相同的规则来进行初始化。
类类型的数据成员,运行该类型的默认构造函数来初始化。
内置或复合类型的成员的初始值依赖于该类对象的作用域:在局部作用域中不被初始化,在全局作用域中被初始化为0。
四、复制构造函数
1、定义: 复制构造函数是一种特殊构造函数,只有1个形参,该形参(常用 const &修饰)是对该类类型的引用。
2、何时使用复制构造函数
两种初始化的形式
- 直接初始化:直接初始化将初始化式放在圆括号中
- 复制初始化:复制初始化使用 = 符号
对于内置类型,例如int, double等,直接初始化和复制初始化没有区别。
对于类类型:
直接初始化直接调用与实参匹配的构造函数;
复制初始化先使用指定构造函数创建一个临时对象
然后用复制构造函数将那个临时对象复制到正在创建的对象。
直接初始化比复制初始化更快。
五、析构函数
1.定义:创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作,例如释放分配的内存、关闭打开的文件等,这个函数就是析构函数。(一个类中有且只有一个析构函数)
2.特点:
- 名字与类名相同
- 在前面需要加上"~"
- 无参数,无返回值
- 一个类最多只有一个析构函数
- 不显示定义析构函数会调用缺省析构函数
4.首先介绍c++创建对象的三种不同形式
- Test p1(1); //栈中分配内存
- Test p2 = Test(2); //栈中分配内存
- Test *p3 = new Test(3); //堆中分配内存
前两个都是在栈中分配内存,在栈中内存由系统自动的去分配和释放
而使用new创建的指针对象是在堆中分配内存
当不需要该对象时,需要我们手动的去释放否则会造成内存泄漏。