欢迎关注本公众号,专注面试题拆解
分享一套视频课程:《C++实现百万并发服务器》 面试需要项目的可以找我获取 ,免费分享。 欢迎V:fb964919126 网络编程系列,已经更新4篇,欢迎阅读:网络编程
空指针能访问成员函数吗?ex: A* p=nullptr;p->f();
看到这道题首先一愣,第一反应这么写不对,但是这是腾讯的面试题,仔细一想,有点意思啊,平时还真是不会去这么思考问题。这是在考成员函数的位置呢,如果直接问成员函数存放在哪里,大部分人能回答上来,换这种问法即使心理有想法,自己没有实际代码编译一下,也不太敢直接回答。(mmp的,面试官这样有意思吗)
我们直接代码实践:
测试验证1:
class A
{
public:
void func(){
std::cout << "func" << std::endl;
}
};
int main()
{
A* p = nullptr;
p->func();
return 0;
}
运行结果:正常打印输出,程序也没有崩溃。
测试验证2:虚函数
class A
{
public:
void func(){
std::cout << "func" << std::endl;
}
virtual void func2(){
std::cout << "func2" << std::endl;
}
};
int main()
{
A* p = nullptr;
p->func();
p->func2();
return 0;
}
运行结果:程序崩溃。
测试验证3:非静态成员变量
class A
{
public:
void func(){
std::cout << "func" << std::endl;
}
int k = 0;
};
int main()
{
A* p = nullptr;
p->func();
p->k = 9;
return 0;
}
运行结果:程序崩溃。
测试验证4:静态成员变量
class A
{
public:
void func(){
std::cout << "func" << std::endl;
}
static int k;
};
int A::k = 0;
int main()
{
A* p = nullptr;
p->func();
p->k = 9;
return 0;
}
运行结果:正常没有崩溃
我们回到测试1,看下它的汇编代码:
可以看到:它底层调用的方式是:A::func
成员函数的位置:
在C++中,类的成员函数并不是存储在类的实例(对象)本身中,而是存储在程序的全局代码段(通常是.text段)中。
类的成员函数实际上是普通的函数,它们被编译成机器码,并存储在程序的全局代码段中。这意味着所有的成员函数都是共享的,并不是每个对象都有自己的副本。
如果类中定义了虚函数,那么每个对象会包含一个指向虚拟表的指针。虚拟表是一个数据结构,它存储了虚函数的地址。这样,当调用虚函数时,程序可以根据对象的实际类型找到正确的函数地址。
成员函数的调用方式:
非虚函数
对于非虚函数,编译器通过调整成员函数的调用机制来实现。具体来说,编译器会将成员函数转换为一个带有额外参数的普通函数,这个参数通常是对象的指针或引用来代替this指针。
class MyClass {
public:
void nonVirtualFunc() {
// 成员函数体
}
};
// 成员函数的实际调用
MyClass obj;
obj.nonVirtualFunc(); // 实际上编译器转化为 MyClass::nonVirtualFunc(&obj);
虚函数:
对于虚函数,编译器会生成一个虚拟表(vtable),并在每个对象中存储一个指向该虚拟表的指针。当调用虚函数时,程序会根据this指针指向的虚拟表来查找并调用正确的函数。
class MyClass {
public:
virtual void virtualFunc() {
// 成员函数体
}
};
// 成员函数的实际调用
MyClass obj;
obj.virtualFunc(); // 实际上编译器转化为 (*obj.vptr)->virtualFunc(&obj);
空指针访问成员函数:
这个本质上要看是否使用到了this指针,如果用到了就会发生崩溃,测试代码1如果改一下,func函数里面打印k的值,也会发生崩溃,因为访问k就是调用了this->k。
class A
{
public:
void func(){
std::cout << "func" << k << std::endl;
}
int k = 9;
};
总结:
类的成员函数并不是存储在类的实例本身中,而是存储在程序的全局代码段中,空指针访问成员函数,如果没有用到this不会出错。
end
CppPlayer
关注,回复【电子书】珍藏CPP电子书资料赠送
精彩文章合集
专题推荐