1、在c++中,结构体中不仅能定义变量,也能定义函数,这在c++中称作类 c++中可以用struct关键字定义类,也可以用class关键字定义类,那这两种方式有什么区别?
我们注意到:
c++中的类有访问限定符
定义一个简单的日期类,class关键字定义的类默认类的成员是私有的,在类外面无法访问;而struct定义的类默认成员是共有的,因为c++的struct要兼容c语言struct的用法。
如果成员函数在类中定义,编译器可能会把函数当成内联函数处理;如果声明和定义分离,在定义的时候,成员函数要加上域名。
2、类的实例化
怎么看一个函数的声明与定义?
只有一个函数名的是函数的声明,有函数实现体的就是定义;
怎么看一个变量的声明与定义?
看编译器有没有给变量开空间;
age作为一个全局变量,编译器是给他开了空间的,但是类里面定义的变量,与结构体类似,当没有初始化的时候,定义的变量没有存储数据,没有开空间,是声明。
当用一个类去定义一个对象的时候,才会开空间,这个过程就叫做类的实例化。
那类或结构体本身是一个声明,不占空间,那是怎么计算大小的呢?
编译器会根据类中的声明来计算大小,类与结构体一样符合内存对齐规则。
当一个头文件定义了一个全局变量时,当头文件在多个cpp文件展开时,就会发生重定义。
1、我们可以用extern 来将定义变成声明
2.用static修饰变量,修改了连接属性,只在当前文件可见,就不会放进链接的符号表。
static int age;
3、怎么计算一个类的大小?类的成员变量可以像结构体一样计算,但是类的成员函数怎么计算?类的成员函数又是存在哪里?
类只保留成员变量,而成员函数会存储在公共代码区。
这样做的意义是什么?
可以保证不同对象调用到同一个成员函数!
如果成员函数也像变量一样存储,就会造成浪费。
date * ptr =nullptr;
ptr->showInfo();
这两行代码的运行结果是什么?
结果是正常运行,因为成员函数没有存在对象里面,并不会对ptr指针解引用。
结构体内存对齐规则
空类的大小是1
用来区分不同空类。
3、this指针
看下面一段函数:
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 a;
};
int main()
{
Date d1, d2;
d1.Init(2022, 1, 11);
d2.Init(2022, 1, 12);
d1.Print();
d2.Print();
return 0;
}
既然成员函数是存储在公共代码区的,编译器怎么区分是d1还是d2调用的成员函数?
c++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象,在函数体中所有成员变量的操作都是通过该指针去访问。但是所有的操作对用户是透明的,不需要用户去传递,编译器自动完成。
编译器处理之后的函数参数应该是这个样子,这样就可以通过指针来区别调用对象。
this指针的特性:
this指针的指针类型为 *const 即不能给this指针赋值。
this指针本质上是形参,对象中不存储this指针
只能在成员函数的内部使用
this指针是成员函数的第一个隐藏形参,不需要用户传递,由编译器通过寄存器传递。