MST
星途 面试题库

面试题:C++常对象与成员函数的深层交互

假设有一个类A,其中有多个成员函数,包括普通成员函数、常成员函数以及静态成员函数。现在定义了一个常对象a,从内存布局和函数调用机制的角度,分析a调用不同类型成员函数的过程和区别。同时,若成员函数内部涉及对成员变量的操作,在常对象调用时会有哪些限制?请结合代码详细阐述。
46.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 内存布局

    • 普通对象在内存中包含成员变量,每个对象的成员变量有自己的存储空间。对于类A的对象,其成员变量占据一定的内存空间。
    • 常对象(如const A a;)同样包含成员变量,不过这些成员变量在对象生命周期内不可修改(除非成员变量被声明为mutable)。
    • 类的成员函数(包括普通、常和静态)并不存储在对象的内存空间中,而是存储在代码段,所有对象共享这些函数代码。静态成员变量存储在全局数据区。
  2. 函数调用机制及区别

    • 普通成员函数
      • 普通对象可以调用普通成员函数。普通成员函数可以修改对象的成员变量。
      • 常对象不能调用普通成员函数,因为普通成员函数可能会修改对象的状态,这与常对象不可变的特性冲突。
      • 例如:
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;
}
  1. 常对象调用成员函数时对成员变量操作的限制
    • 常对象调用普通成员函数会导致编译错误,因为普通成员函数可能修改对象状态。
    • 常对象调用常成员函数时,不能修改非mutable成员变量。mutable关键字修饰的成员变量可以在常成员函数中被修改。
    • 静态成员函数由于不依赖于对象状态,常对象调用时对成员变量(这里指静态成员变量)的操作没有特殊限制,只要符合静态成员函数本身对成员变量访问的规则(即只能访问静态成员变量)即可。