✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
10. thi s 指针相关问题
10.1 什么是 this 指针?
this 实际上是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给 this。不过 this 这个形参是隐式的,它并不出现在代码中,而是在编译阶段由编译器默默地将它添加到参数列表中。
this 作为隐式形参,本质上是成员函数的局部变量,所以只能用在成员函数的内部,并且只有在通过对象调用成员函数时才给 this 赋值。
成员函数最终被编译成与对象无关的普通函数,除了成员变量,会丢失所有信息,所以编译时要在成员函数中添加一个额外的参数,把当前对象的首地址传入,以此来关联成员函数和成员变量。这个额外的参数,实际上就是 this,它是成员函数和成员变量关联的桥梁。
10.2 this 的使用事项
-
this 是 const 指针,它的值是不能被修改的,一切企图修改该指针的操作,如赋值、递增、递减等都是不允许的。
-
this 只能在成员函数内部使用,用在其他地方没有意义,也是非法的。
-
只有当对象被创建后 this 才有意义,因此不能在 static 成员函数中使用。
10.3 t his 指针存储在哪?
其实编译器在生成程序时加入了获取对象首地址的相关代码。并把获取的首地址存放在了寄存器 ECX 中 (VC++ 编译器是放在 ECX 中,其它编译器有可能不同)。也就是成员函数的其它参数正常都是存放在栈中。而 this 指针参数则是存放在寄存器中。
类的静态成员函数因为没有 this 指针这个参数,所以类的静态成员函数也就无法调用类的非静态成员变量。
11. C ++ 空类相关问题
11.1 C+ + 一个空类占多少字节?
在 C++ 中空类会占 1 个字节,这是为了让对象的实例能够相互区别。具体来说,空类同样可以被实例化,并且每个实例在内存中都有独一无二的地址,因此,编译器化的过程就是在内存中分配一块地址。
11.2 如果空类内含有虚函数,类的大小又是多少?
如果一个空类内含有虚函数,那么这个类的大小至少是 4 字节(32 位系统中)或 8 字节(64 位系统中)。这是因为每个对象都需要一个虚函数表指针来指向类的虚函数表,而虚函数表指针本身需要一定的存储空间。因此,即使类是空的,编译器也会为该类隐含添加一个字节,以确保每个对象的地址都是唯一的 。
11.3 什 么是空白基类最优化?
当该空白类作为基类时,该类的大小就优化为 0 了,这就是所谓的空白基类最优化。
空白基类最优化无法被施加于多重继承上只适合单一继承。
11.4 C ++ 一个空类默认有哪几个函数,请写出函数定义
C++的空类会有 6 个默认的函数。即 默认构造函数、默认拷贝构造函数、默认析构函数、默认赋值运算符,这四个是我们通常知道的。但是除了这四个,还有两个,那就是取址运算符和 const 取址运算符,即总共有六个函数。
示例如下:
class Empty{
public:
Empty(); // 缺省构造函数
Empty( const Empty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty& operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符 const
};
但是,C++ 默认生成的函数,只有在被需要的时候,才会产生。即当我们定义一个类,而不创建类的对象时,就不会创建类的构造函数、析构函数等。
12. 虚 函数原理?
允许在派生类中重新定义基类中的函数,并且在运行时根据对象的实际类型来调用相应的函数。虚函数的实现依赖于虚函数表(vtable)和虚函数指针(vpointer)
1. 虚函 数的声明和定义:
在基类中,将希望被派生类重写的函数声明为虚函数。使用 virtual
关键字来标记虚函数。
class Base {
public:
virtual void foo() {
// Base class implementation
}
};
2. 虚函数表(vtable):
-
对于每个包含虚函数的类,编译器会为其创建一个虚函数表,该表是一个指针数组,其中存储了虚函数的地址。
-
虚函数表是在程序运行时分配和维护的,每个包含虚函数的对象都有一个指向其类的虚函数表的指针。
-
虚函数表包含了该类中所有虚函数的地址,按照它们在类中声明的顺序排列。
3. 虚函数 指针(vpointer):
-
对于每个包含虚函数的对象,编译器会在对象的内存布局中添加一个虚函数指针(通常位于对象的开头)。
-
虚函数指针指向该对象的虚函数表,这样程序可以在运行时动态查找并调用适当的虚函数。
4. 动态分 派:
-
当通过基类指针或引用调用虚函数时,程序会使用虚函数指针来查找该对象的虚函数表。
-
然后,程序根据函数在虚函数表中的位置来调用相应的虚函数。
-
这个过程称为动态分派,因为它在运行时根据对象的实际类型来决定调用哪个函数。