面试题答案
一键面试-
内存布局:
- 普通对象在内存中包含成员变量,每个对象的成员变量有自己的存储空间。对于类
A
的对象,其成员变量占据一定的内存空间。 - 常对象(如
const A a;
)同样包含成员变量,不过这些成员变量在对象生命周期内不可修改(除非成员变量被声明为mutable
)。 - 类的成员函数(包括普通、常和静态)并不存储在对象的内存空间中,而是存储在代码段,所有对象共享这些函数代码。静态成员变量存储在全局数据区。
- 普通对象在内存中包含成员变量,每个对象的成员变量有自己的存储空间。对于类
-
函数调用机制及区别:
- 普通成员函数:
- 普通对象可以调用普通成员函数。普通成员函数可以修改对象的成员变量。
- 常对象不能调用普通成员函数,因为普通成员函数可能会修改对象的状态,这与常对象不可变的特性冲突。
- 例如:
- 普通成员函数:
class A {
private:
int data;
public:
A(int value) : data(value) {}
void normalFunction() {
data++;
}
};
int main() {
A obj(10);
obj.normalFunction();// 普通对象可以调用
const A a(20);
// a.normalFunction(); // 错误,常对象不能调用普通成员函数
return 0;
}
- 常成员函数:
- 普通对象和常对象都可以调用常成员函数。常成员函数不能修改对象的成员变量(除非成员变量被声明为
mutable
),这是为了保证常对象的状态不变。 - 在常成员函数内部,
this
指针是一个指向const A
的指针,限制了对成员变量的修改。 - 例如:
- 普通对象和常对象都可以调用常成员函数。常成员函数不能修改对象的成员变量(除非成员变量被声明为
class A {
private:
int data;
public:
A(int value) : data(value) {}
void normalFunction() {
data++;
}
void constFunction() const {
// data++; // 错误,不能在常成员函数中修改非mutable成员变量
}
};
int main() {
A obj(10);
obj.constFunction();
const A a(20);
a.constFunction();
return 0;
}
- 静态成员函数:
- 静态成员函数不属于任何一个对象,普通对象和常对象都可以调用静态成员函数,也可以通过类名直接调用(如
A::staticFunction()
)。 - 静态成员函数没有
this
指针,因为它不依赖于任何特定对象,所以不能直接访问非静态成员变量。它只能访问静态成员变量和其他静态成员函数。 - 例如:
- 静态成员函数不属于任何一个对象,普通对象和常对象都可以调用静态成员函数,也可以通过类名直接调用(如
class A {
private:
static int staticData;
int data;
public:
A(int value) : data(value) {}
static void staticFunction() {
staticData++;
// data++; // 错误,不能在静态成员函数中访问非静态成员变量
}
};
int A::staticData = 0;
int main() {
A obj(10);
obj.staticFunction();
const A a(20);
a.staticFunction();
A::staticFunction();
return 0;
}
- 常对象调用成员函数时对成员变量操作的限制:
- 常对象调用普通成员函数会导致编译错误,因为普通成员函数可能修改对象状态。
- 常对象调用常成员函数时,不能修改非
mutable
成员变量。mutable
关键字修饰的成员变量可以在常成员函数中被修改。 - 静态成员函数由于不依赖于对象状态,常对象调用时对成员变量(这里指静态成员变量)的操作没有特殊限制,只要符合静态成员函数本身对成员变量访问的规则(即只能访问静态成员变量)即可。