前言
- 大家好吖,欢迎来到 YY滴 C++系列 ,热烈欢迎!
- 【 '类与对象'-三部曲】的大纲主要内容如下:
- 如标题所示,本章是【 '类与对象'-三部曲】三章中的第二章节——类章节,主要内容如下:
一.类
C++兼容C,C语言中的结构体strcut也算是一种类,是public(公有)的,可以被类外直接访问。
类中的函数默认是内联函数,具体是否是内联函数编译器会判断。如果将其定义和声名分开,即类放在.h文件,定义函数放在.cpp文件,函数不为内联函数;
1.类的组成与计算类的大小(含结构体内存对齐规则)
- 类由访问限定符划分,类中既有成员变量,又有成员函数;
计算类的大小,只用考虑成员变量的大小
例如:上图中,类的大小为8字节
PS:内存对齐,本质上是牺牲空间换取效率。通过调整默认对齐数可以对这一过程进行动态调整。
二. 空类的大小
没有成员变量的类对象,需要 1byte ,是为了占位,表示对象存在.
三.内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中 的所有成员。但是外部类不是内部类的友元。
特性:
内部类可以定义在外部类的public、protected、private都是可以的。
注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
sizeof(外部类)=外部类,和内部类没有任何关系。
四.类的六个默认成员函数
特点:
当没有显式定义(我们不主动写时),编译器会自动生成
1.构造函数(第一个)
默认构造函数(3种):(1) 类自己生成的函数(2)无参 (3)全缺省的函数
特征: (不传参就可以调用)
构造函数的主要任务是初始化对象,如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义,编译器将不再生成。
运作上看,当对象实例化时,编译器会自动调用它
形态上看,其名字与类名相同,且无返回值
注意点,构造函数允许重载
一.什么时候需要自己写构造函数?
需要自己写的情况:
一般情况下,有内置类型成员,要自己写(否则会初始化成随机值)
不需要自己写的情况:
当内置类型成员都有缺省值时,且初始化符合要求,可以考虑让编译器自己生成
全部都是自定义类型成员(例如:Stack),可以考虑让编译器自己生成
注意!!!
二.构造函数可以使用重载和不可以使用重载的情况
- 构造函数可以用重载的情况:
typedef int DataType; class Stack { public: Stack(DataType* a, int n) //特定初始化 { cout << "Stack(DataType* a, int n)" << endl; _array = (DataType*)malloc(sizeof(DataType) * n); if (NULL == _array) { perror("malloc申请空间失败!!!"); return; } memcpy(_array, a, sizeof(DataType) * n); _capacity = n; _size = n; } //调用时可用以用d1,使用上方的构造函数 Stack d1(int, 11); //Stack d1(); // 不可以这样写,会跟函数声明有点冲突,编译器不好识别 Stack d2; //调用时可以用d2,使用下方的构造函数 Stack(int capacity = 4) //构造函数(全缺省) { cout << "Stack(int capacity = 4)" << endl; _array = (DataType*)malloc(sizeof(DataType) * capacity); if (NULL == _array) { perror("malloc申请空间失败!!!"); return; } _capacity = capacity; _size = 0; } /*以下代码仅为完整性 void Push(DataType data) { CheckCapacity(); _array[_size] = data; _size++; } void Pop() { if (Empty()) return; _size--; } DataType Top() { return _array[_size - 1]; } int Empty() { return 0 == _size; } int Size() { return _size; } ~Stack() { cout << "~Stack()" << endl; if (_array) { free(_array); _array = NULL; _capacity = 0; _size = 0; } } private: void CheckCapacity() { if (_size == _capacity) { int newcapacity = _capacity * 2; DataType* temp = (DataType*)realloc(_array, newcapacity * sizeof(DataType)); if (temp == NULL) { perror("realloc申请空间失败!!!"); return; } _array = temp; _capacity = newcapacity; } }*/ private: DataType* _array; int _capacity; int _size; };
构造函数不能用重载的情况:无参调用存在歧义
// 构成函数重载 // 但是无参调用存在歧义 Date() { _year = 1; _month = 1; _day = 1; } Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; }