目录
一:类的作用域
二:类的实例化
三:类的对象模型
3.1如何计算类对象的大小
7.2类对象的存储方式猜测
3.3结构体内存对其规则
四:this指针
8.1this指针的引出
8.2this指针的特性
4.3C语言和C++实现Stack的对比
一:类的作用域
类定义了一个域,类的所有成员都在类的作用域中。在类外定义变量成员时,需要使用::作用域限定符指明成员属于哪个域
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[10];
int _age;
};
//这里指定PrintPersonInfo是属于Person这个域的
void Person::PrintPersonInfo()
{
cout << "_name" << " " << "_gender" << " " << " age" << endl;
}
二:类的实例化
用类类型创建对象的过程,称为类的实例化
1.类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来储存它;比如:入学时填写的学生信息表,表格就可以看作是一个类,来描述具体的学生信息
类就像是一个迷题,对谜底进行描述,谜底就是谜语的一个实例
2.一个类可以实例化出多个变量,实例化出的对象,占用的实际的物理空间,存储类的成员变量
int main()
{
Person._age = 100;//编译失败:error 语法错误
return 0;
}
Person类是没有空间的,只有Person类的实例化出的对象才有具体的年龄
3.做个比方,类实例化出对象就像现实中使用建筑设计图创建出房子,类就像设计图,只设计需要什么东西,实际上并没有实体的建筑存在,同样类也是一个设计,实例化出对象才能实际存储东西,占物理空间
三:类的对象模型
3.1如何计算类对象的大小
class A
{
public:
void PrintA()
{
cout << "_a" << endl;
}
private:
char _a;
};
问题::类中既可以有成员变量,也可以有成员函数,那么一个类的对象中包含了什么?如何计算类的大小?
7.2类对象的存储方式猜测
成员中包含类的各个成员
缺陷:每个对象中的成员变量是不同的,但是调用的函数是相同的,如果按照这种此种方式存储,当一个类创建多个对象时,每个对象中都会保存一份代码,相同的代码保存多次,浪费空间,那么如何解决呢?
代码只保存一份,在对象中保存代码的地址
只保存成员变量,成员函数放在公共的代码段
问题:对于上述三种存储方式,那么计算机到底是按照那种方式来存储的?
我们可以通过下面的代码分析得出结论:
//类中既有成员变量又有成员函数
class A1
{
public:
void f1(){}
private:
int _a;
};
//类中仅有成员函数
class A2
{
public:
void f2(){}
};
//类中什么都没有空类
class A3
{
};
首先对于A1,来说:
通过求A1的字节大小,可以得出答案,应该是第三种方案
那么空类的字节大小是多少?是0吗?
为什么空类没有成员变量,字节大小是一呢?
前面实例化时有讲到,对于函数变量的定义是开辟了空间给变量,如果空类的字节大小是0,那么下面的情况如何解释?
如果字节大小是零,变量的定义好的条件又是开辟空间,不就自相矛盾了吗?
所以空类的大小是1,这个1不存储有效数据,只是标识变量已经开辟出来了
结论:
一个类的大小,实际上就是该类中“成员变量之和”,当然要注意内存对齐
注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象
3.3结构体内存对其规则
四:this指针
8.1this指针的引出
我们先定义一个日期类Date
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << "_year" << "-" << "_month" << "-" << "_day" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1, d2;
d1.Init(2024, 4, 5);
d1.Print();
d2.Init(2023, 4, 4);
d2.Print();
return 0;
}
译器自动完成。
8.2this指针的特性
this指针存在哪里?
this指针作为形参存放在栈中,但是由于this指针频繁使用,优点编译器会进行优化,存放在寄存器中
4.3C语言和C++实现Stack的对比
1.C语言实现
typedef int DataType;
typedef struct Stack
{
DataType* array;
int capacity;
int size;
}Stack;
void StackInit(Stack* ps)
{
assert(ps);
ps->array = (DataType*)malloc(sizeof(DataType) * 3);
if (NULL == ps->array)
{
assert(0);
return;
}
比特就业课
ps->capacity = 3;
ps->size = 0;
}
void StackDestroy(Stack* ps)
{
assert(ps);
if (ps->array)
{
free(ps->array);
ps->array = NULL;
ps->capacity = 0;
ps->size = 0;
}
}
void CheckCapacity(Stack* ps)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity * 2;
DataType* temp = (DataType*)realloc(ps->array,
newcapacity*sizeof(DataType));
if (temp == NULL)
{
perror("realloc申请空间失败!!!");
return;
}
ps->array = temp;
ps->capacity = newcapacity;
}
}
void StackPush(Stack* ps, DataType data)
{
assert(ps);
CheckCapacity(ps);
ps->array[ps->size] = data;
ps->size++;
}
int StackEmpty(Stack* ps)
{
assert(ps);
return 0 == ps->size;
}
void StackPop(Stack* ps)
{
if (StackEmpty(ps))
return;
ps->size--;
}
DataType StackTop(Stack* ps)
{
assert(!StackEmpty(ps));
return ps->array[ps->size - 1]
};
typedef int DataType;
class Stack
{
public:
void Init()
{
_array = (DataType*)malloc(sizeof(DataType) * 3);
if (NULL == _array)
{
perror("malloc申请空间失败!!!");
return;
}
_capacity = 3;
_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;}
void Destroy()
{
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;
};
int main()
{
Stack s;
s.Init();
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
printf("%d\n", s.Top());
printf("%d\n", s.Size());
s.Pop();
s.Pop();
printf("%d\n", s.Top());
printf("%d\n", s.Size());
s.Destroy();
return 0;
}