6.1结构体
结构体的创建
struct student {
//char name[100];
string name;
int age;
bool gender;
}lisi,zhaoliu,wangwu;//20年前的写法
结构体数据的赋值
student zhangsan = { "张三",23,true };
cout << zhangsan.name << endl;
内存对齐
默认对齐,先看结构体中内存最大的那个
如果不够,会向下紧挨着的数据进行合并,合并成内存最大的那个
如果下面没有其他数据了,会自动补充到内存最大的那个
如果合并下面数据内存超了,上面会自动补充到内存最大的那个
struct ABC {
int a;
char b;
float c;
char d;
};
cout << sizeof(ABC) << endl;
结构体创建指针
struct student {
string name;
int age;
bool gender;
};
student zhangsan = { "张三",23,true };
student* p = &zhangsan;
cout << p->name << endl;
结构体用指针new创建的对象
//student* p = new student;
student* p = new student{ "张三",23,true };
cout << p->name << endl;
delete p;
创建结构体数组举例
student arr[5];
arr[0] = { "张三",23,true };
cout <<arr[0].name<< endl;
student arr[2] = { { "张三",23,true } ,{ "李四",25,false } };
cout << arr[0].name << endl;
cout << arr[1].name << endl;
//也可以这样创建指针
student* p = new student[2]{ { "张三",23,true } ,{ "李四",25,false } };
结构体构造函数
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}//无参的构造函数
ListNode(int x) : val(x), next(nullptr) {}//带参数的构造函数
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
调用
ListNode *p = new ListNode();//无参的
ListNode *p = new ListNode(0);有参的
//不用new创建
ListNode head;//相当于创建了一个头节点对象,调用无参构造
ListNode *p = &head;
6.2类
类的创建
class Car
{
public:
string name;
int price;
void Move() {
cout << "移动" << endl;
}
};
一般情况下不会用构造器直接给对象赋值,而是用构造函数
Car benzi;
Car benz("本田",2354);
cout << benz.name << endl;
C++的类中系统会提供的默认的函数(4个)
- 1.默认构造函数
没有任何参数的构造函数都可以叫默认构造函数,如果类中没有任何构造函数,系统会提供一个看不到的默认构造函数,但是如果写了任意形式的构造函数,那么默认构造函数会消失
构造函数是一个特殊的函数,没有返回值,功能是这个类创建的时候会被自动调用一次
Car() {
cout << "默认构造函数" << endl;
}
- 2.析构函数
没有返回值,连void也不用,不能写参数,函数的名字和类名一样,但是在类名前加~,这个类的对象被删除回收内存的时候,这个函数会被自动调用一次
~Car() {
cout << "这个对象被删除了" << endl;
}
-
补充
构造函数与析构函数的区别
构造函数可以重载,析构函数不能重载,因为析构函数没有返回值,没有参数 -
3.拷贝构造函数
拷贝构造函数是一个特殊的构造函数,功能在于快速的将自己的所有属性赋值给另一个同类型的对象
Car (const Car& car) {
this->name = car.name;
this->price = car.price;
}
使用
Player zhangsan("张三",100);
Player lis(zhangsan);
- 4.赋值运算符的重载函数
赋值符号=
如果在类的初始化直接使用=,就是等于直接使用拷贝构造函数
如果在之后使用=,就是等于使用赋值运算符的重载
Player wangwu = zhangsan;
lisi = zhangsan;
赋值运算符的重载
void operator =(Player& p) {
hp = p.hp;
name = p.name;
}
- 补充
运算符重载
在运算符的前面加operator,函数的名字是运算符
void operator + (int n) {
hp += n;
}
类对象在调用这种函数的时候无需加.操作符,运算符右边的值就是参数,无需加()
zhangsan + 10;
补充(友元)
是函数也可以是类,友元的函数或者友元的类可以访问指定的类中的私有成员或者函数
设定B是A类的友元,那么B中可以访问任意A的成员(包括私有和保护)
不推荐使用
class Player {
private:
int hp;
string name;
friend class Monster;
friend void show(Player a);
public:
Player() {
}
Player(string _name, int _hp) {
name = _name;
hp = _hp;
}
};
void show(Player a) {
cout << a.hp << endl;
}
class Monster {
private:
string name;
int atk;
public:
Monster() {
}
Monster(string _name, int _atk) {
name = _name;
atk = _atk;
}
void attack(Player p) {
p.hp = p.hp - atk;
cout << "干他" << endl;
}
};