面试题答案
一键面试this指针工作原理
- 隐含参数:在C++中,每一个非静态成员函数都隐含一个指向调用该函数对象的指针,即
this
指针。它作为一个隐含参数传递给成员函数,编译器会自动处理这个过程。例如,对于类A
的成员函数func
,实际编译器处理时类似于func(A* this)
。 - 对象区分:当不同对象调用同一个成员函数时,
this
指针指向不同的对象实例,从而成员函数能够访问到对应对象的数据成员。例如:
class A {
public:
int data;
void setData(int value) {
this->data = value;
}
};
A obj1, obj2;
obj1.setData(10);
obj2.setData(20);
在obj1.setData(10)
调用中,this
指针指向obj1
;在obj2.setData(20)
调用中,this
指针指向obj2
,这样就能分别设置不同对象的data
成员。
影响效率的操作
- 访问数据成员方式
- 直接访问与间接访问:如果数据成员是通过复杂的指针或引用链来访问,会增加寻址时间,降低效率。例如:
class B {
public:
int* ptr;
void accessData() {
int value = (*ptr);
}
};
相比直接访问int value = data;
(假设data
是直接成员变量),通过指针ptr
访问数据需要额外的指针解引用操作,增加了时间开销。
- 多层嵌套访问:如果数据成员是嵌套在复杂的数据结构中,如多层嵌套的结构体或类成员,访问时需要逐层解析,也会影响效率。例如:
struct Inner {
int num;
};
struct Outer {
Inner inner;
};
class C {
public:
Outer outer;
void accessInnerData() {
int value = outer.inner.num;
}
};
- 成员函数声明方式
- 虚函数:虚函数调用涉及到虚函数表的查找,会带来额外的开销。当一个成员函数被声明为虚函数时,编译器会为类生成虚函数表,在调用虚函数时,需要通过虚函数表指针找到对应的函数地址,这比直接调用非虚函数的效率低。例如:
class Base {
public:
virtual void virtualFunc() {
// 函数体
}
};
class Derived : public Base {
public:
void virtualFunc() override {
// 重写函数体
}
};
Base* basePtr = new Derived();
basePtr->virtualFunc();
这里通过基类指针调用虚函数virtualFunc
,就需要通过虚函数表来确定实际要调用的Derived
类的virtualFunc
函数,有额外开销。
- 内联函数:虽然内联函数旨在提高效率,但是如果内联函数体过大,编译器可能不会进行内联展开,导致函数调用开销仍然存在。同时,过度使用内联函数会使代码体积增大,可能导致缓存命中率降低,间接影响效率。例如:
class D {
public:
inline void largeInlineFunc() {
// 非常长的函数体
}
};
编译器可能因为函数体过大而不进行内联展开,使得调用largeInlineFunc
时仍有函数调用开销。