前言
前一章节,简单描述了C++的入门基础知识,今天主要描述C++中的类和对象到底是什么?
1、C++中的类
- 类的基本定义格式:在C++中类主要包含成员函数(方法)和成员变量(属性)。下面是类的基本定义:
//类的定义格式
calss 类名
{
1、成员方法/函数
2、成员属性/变量
};
//记住最后的分号
通过一个栈类来了解:
//栈类的定义
#include<iostream>
using namespace std;
//class类中默认是private访问权限
class Stack
{
public:
//成员方法/函数
//1、初始化函数
void init(int n=4)
{
array = (int*)malloc(sizeof(int)*n);
if (array == nullptr)
{
perror("malloc 申请失败!");
return;
}
else
{
capacity = n;
top = 0;//若取栈顶元素的话,需要top-1
}
}
//2、入栈操作
void Push(int x)
{
//检测扩容
if (capacity == top)
{
size_t new_capacity = capacity * 2;
int* tmp = (int*)realloc(array, sizeof(int) * new_capacity);
if (tmp == nullptr)
{
perror("reall 扩容失败!");
return;
}
else
{
array = tmp;
capacity = new_capacity;
}
}
//插入数据
array[top++] = x;
}
//3、取栈顶元素
int Top()
{
if (top > 0)
{
return array[top - 1];
}
else
{
cout << "栈中无元素!" << "\n";
return 0;
}
}
//4、销毁函数
void Destroy()
{
free(array);
array = nullptr;
capacity = top = 0;
}
private:
//成员属性/变量,此处只是变量声明不是定义,还没有分配内存空间的
int* array;
size_t capacity;
size_t top;
};//分号不能省
int main()
{
Stack st;
st.init();
st.Push(1);
st.Push(2);
st.Push(3);
st.Push(4);
st.Push(5);
cout << "栈顶元素:" << st.Top() << "\n";
st.Destroy();
return 0;
}
- 定义类的成员变量的方式
①在C++中为了区分成员变量,一般会在成员变量名前面加上
_
或者m
;
- 我们知道在C语言中
struct
是用来定义结构体的,而在C++中struct
也可以用来定义类,一般情况下都是用class
。 - 注意:定义在类里面的成员函数默认是
inline
(内联函数)。
下面是日期类例子:
#include<iostream>
using namespace std;
class Date
{
public:
//给成员变量赋初始值
void Init(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
//打印函数
void Print()
{
cout << _year << "年" << _month << "月" << _day << "日" << "\n";
}
private:
//为了区分成员变量,在开头加_
int _year;
int _month;
int _day;
};
int main()
{
Date date;
date.Init(2024, 7, 12);
date.Print();
return 0;
}
2、C++中的访问限定修饰符
访问限定修饰符:主要是控制外部用户对类中成员属性和成员方法的使用权限。格式就是在定义成员函数和成员属性的开头写如
private:
3、类域
前一章节说到C++中有多个域,包括函数局部域、全局域、命名空间域、类域;
其中要说的是类域,也就是class括号括起来的所有。
类域影响的是编译的查找规则,因此在成员函数声明和定义分离的时候就需要指明是哪个类的,要用到域操作符::
例如下面:
分开的时候,不用域操作符,会出现未定义标识符错误。
加上之后才可以:
//成员函数声明和定义分离的时候
#include<iostream>
using namespace std;
class Student
{
public:
//只做函数声明
void Init(string name, int age, string gender);
void Print();
private:
string _name;
int _age;
string _gender;
};
//成员函数的定义
void Student::Init(string name, int age, string gender)
{
_name = name;
_age = age;
_gender = gender;
}
void Student::Print()
{
cout << "姓名:" << _name << "\n";
cout << "年龄:" << _age << "\n";
cout << "性别:" << _gender << "\n";
}
int main()
{
Student st1;
st1.Init("张三", 25, "男");
st1.Print();
return 0;
}
结果如下:
4、实例化
- 概念:用类的类型在物理内存中创建对象,就称之为类实例化出对象。
- ⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。
一个学生类可以有很多个学生:
int main()
{
Student st1;
st1.Init("张三", 25, "男");
st1.Print();
Student st2;
st2.Init("李四",30,"男");
st2.Print();
return 0;
}
- C++规定类实例化的对象也要符合内存对⻬的规则。
内存对⻬规则
• 第⼀个成员在与结构体偏移量为0的地址处。
• 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
• 注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。
• VS中默认的对⻬数为8
• 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。
• 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。
#include<iostream>
using namespace std;
class A
{
public:
void Print()
{
cout << "只有一个成员函数占多少字节?" << "\n";
}
};
class B
{
public:
void Print()
{
cout << "有一个成员函数和成员属性占多少字节?" << "\n";
}
private:
int _number;
char _ch;
};
class C
{
//空
};
int main()
{
A a;
B b;
C c;
cout << "A类占字节:" << sizeof(a) << "\n";
cout << "B类占字节:" << sizeof(b) << "\n";
cout << "C类占字节:" << sizeof(c) << "\n";
return 0;
}
为什么类中没有成员变量和类中为空也占1个字节?主要是为了占位标识对象存在。