类的引入
目录
在c语言中我们的结构体只能创建变量,在c++中呢结构体不仅可以定义变量还可以创建函数,例如手写的栈,结构体中只是用来创建变量而c++中可以定义函数
简约代码如下
#include<string.h>
#include<cstring>
#include<iostream>
using namespace std;
typedef int datatype;
typedef struct stu {
void indit(int _capacity)
{
array = (datatype*)malloc(sizeof(datatype) *_capacity);
if (array == NULL)
{
perror("malloc::false\n");
}
capacity = _capacity;
size = 0;
}
void push(int x)
{
//....此处省略一大段列如扩容之类的代码
array[size++] = x;
}
int top()
{
//省略代码
return array[size - 1];
}
void destroy()
{
if (array)
{
free(array);
array = nullptr;
size = 0;
capacity = 0;
}
}
datatype* array;
int size;
int capacity;
}stu;
int main()
{
stu s;
s.indit(4);
s.push(4);
s.push(5);
cout << s.top();
return 0;
}
//这段代码大家可以拷贝下来查看运行结果
上面结构体的定义呢我们在c++中更喜欢用class进行。
类的定义
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
class classname { //类体 };//一定要注意这里的分号
类体 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
类的作用域
类定义了一个新的作用域所有类的成员都在这个作用域中。在类体外定义成员需要使用::作用域操作符指明成员属于哪个类域
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
cout << _name << " "<< _gender << " " << _age << endl;
}
类的实例化
用类类型创建对象的过程叫做类的实例化
1:类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类但是并没有分配实际的内存空间来存储它,列如入学时填写的学生信息表表格可以看成一个类来描述学生的具体信息。
2:一个类可以实列出多个对象实例出的对象占用了实际的内存空间存储成员变量。
3.:做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
类对象模型
如何计算类的内存大小
类中既有成员变量又有成员函数那么一个类的内存大小应当如何计算呢?他的对象包含了什么呢?
猜测1 类中包含了各个成员,包含了各种变量和函数,
此猜测的缺陷是不同的对象成员是不一样的但是如果调用相同的成员函数的话那么如果保存多个对象就会导致内存中很大一部分的代码是相同的,会浪费空间。
猜测二 将成员函数的代码只保存一份而在对象中呢只保存成员函数的地址。如下图所示
猜测三 还有一种只保存成员变量而成员函数则保存在一个共同的代码段里面这样子的话就可以省下空间
那么对于以上三种存储方式计算机究竟是按照那种存储方式进行存储的呢?我们可以通过代码来验证。
#include<iostream>
using namespace std;
class Time {
public:
void f1()
{
return;
}
private:
int year;
int day;
int month;
};
class ff {
public:
void fun1()
{
return;
}
};
class A1{
};
int main()
{
cout << sizeof(ff) << "ff" << endl;;
cout << sizeof(Time) << "Time" << endl;
cout<<sizeof(A1)<<"A1"<<endl;
return 0;
}
运行截图如下
一个类的大小实际上就是类中成员变量之和(主意内存对齐)
这里呢在复习一下结构体的内存对齐
1. 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
当然了对于空类编译器呢仍然是给了一个字节的内存大小进行区别的。
类的两种定义方式
第一种:类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加 (类名::)
#include<string.h>
#include"game.h"
#include<cstring>
#include<iostream>
using namespace std;
typedef int datatype;
void person::print()
{
cout << name << "-" << sex << "-" << score;
}
void person::ccin()
{
cin >> name >> sex >> score;
}
int main()
{
person stu;
stu.ccin();
stu.print();
return 0;
}
//.h文件
#include<iostream>
using namespace std;
class person {
public:
void print();
void ccin();
private:
char name[100];
char sex[100];
int score;
};
第二种就是不管是定义还是实现都在 .cpp 文件中
#include<string.h>
#include<cstring>
#include<iostream>
using namespace std;
typedef int datatype;
class person {
public:
void print()
{
cout << name << ' ' << sex << ' ' << score;
}
void ccin()
{
cin >> name >> sex >> score;
}
private:
char name[100];
char sex[100];
int score;
};
int main()
{
person stu;
stu.ccin();
stu.print();
return 0;
}
成员变量名的命名规则:其实就是加个后缀之类的便于区分形参和类的成员变量当然我们要根据不同的环境进行取名字。