一、类和对象
1.1、委托构造函数
类中往往有多个构造函数,只是参数表和初始化列表不同,其初始化算法都是相同的,这时,为了避免代码重复,可以使用委托构造函数。
Clock类的两个构造函数:
Clock(int newH, int newM, int newS) : hour(newH),minute(newM), second(newS) { //构造函数
}
Clock::Clock(): hour(0),minute(0),second(0) { }//默认构造函数
l 委托构造函数使用类的其他构造函数执行初始化过程
l 例如:
Clock(int newH, int newM, int newS): hour(newH),minute(newM), second(newS){
}
Clock(): Clock(0, 0, 0) { }
1.2、复制构造函数
复制构造函数是一种特殊的构造函数,其形参为本类的对象引用。作用是用一个已存在的对象去初始化同类型的新对象。
class 类名 {
public :
类名(形参);//构造函数
类名(const 类名 &对象名);//复制构造函数
// ...
};
类名::类( const 类名 &对象名)//复制构造函数的实现
{ 函数体 }
隐含的复制构造函数
-
如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个隐含的复制构造函数。
-
这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。
“=delete”
-
如果不希望对象被复制构造
-
C++98做法:将复制构造函数声明为private,并且不提供函数的实现。
-
C++11做法:用“=delete”指示编译器不生成默认复制构造函数。
复制构造函数被调用的三种情况
- 定义一个对象时,以本类另一个对象作为初始值,发生复制构造;
- 如果函数的形参是类的对象,调用函数时,将使用实参对象初始化形参对象,发生复制构造;
- 如果函数的返回值是类的对象,函数执行完成返回主调函数时,将使用return语句中的对象初始化一个临时无名对象,传递给主调函数,此时发生复制构造。这种情况也可以通过移动构造避免不必要的复制。
1.3、析构函数
-
完成对象被删除前的一些清理工作。
-
在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。
-
如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数,其函数体为空。
-
构造函数和析构函数举例
#include using namespace std; class Point { public: Point(int xx,int yy); ~Point(); //...其他函数原型 private: int x, y; };
1.4、结构体
-
结构体是一种特殊形态的类
-
与类的唯一区别:类的缺省访问权限是private,结构体的缺省访问权限是public
-
结构体存在的主要原因:与C语言保持兼容
-
什么时候用结构体而不用类
-
定义主要用来保存数据、而没有什么操作的类型
-
人们习惯将结构体的数据成员设为公有,因此这时用结构体更方便
结构体的定义
struct 结构体名称 {
公有成员
protected:
保护型成员
private:
私有成员
};
结构体的初始化
- 如果一个结构体的全部数据成员都是公共成员,并且没有用户定义的构造函数,没有基类和虚函数(基类和虚函数将在后面的章节中介绍),这个结构体的变量可以用下面的语法形式赋初值
类型名 变量名 = { 成员数据1初值, 成员数据2初值, …… };
联合体
union 联合体名称 {
公有成员
protected:
保护型成员
private:
私有成员
};
特点
- 成员共用同一组内存单元
- 任何两个成员不会同时有效