MST

星途 面试题库

面试题:C++类中const成员函数和const对象

在C++类中,const成员函数和const对象之间有什么联系和限制?为什么有些成员函数需要声明为const?如果一个类中有mutable成员变量,在const成员函数中对其进行修改是否合法?请结合代码示例详细阐述。
16.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. const成员函数和const对象之间的联系和限制

  • 联系:const对象只能调用const成员函数。这是因为非const成员函数可能会修改对象的状态,而const对象的状态是不允许被修改的,所以编译器只允许const对象调用不会修改对象状态的const成员函数。
  • 限制
    • 非const对象既可以调用const成员函数,也可以调用非const成员函数。
    • const成员函数不能修改对象的非mutable数据成员(除非这些数据成员被声明为mutable),因为其设计初衷就是保证在调用函数时对象状态不被改变。

2. 为什么有些成员函数需要声明为const

  • 表明函数不会修改对象状态:这样可以让代码的意图更清晰,调用者可以明确知道调用该函数不会改变对象的内部数据。例如,访问器(getter)函数通常会声明为const,因为它们只是返回对象的某些属性值,而不应该修改对象。
  • 提高函数的可复用性:一个声明为const的成员函数既可以被const对象调用,也可以被非const对象调用。如果没有声明为const,就只能被非const对象调用,限制了函数的使用场景。

3. mutable成员变量在const成员函数中的修改合法性

在C++中,mutable关键字修饰的成员变量可以在const成员函数中被修改。这是因为mutable变量的设计目的就是为了允许在const成员函数中改变其值,用于一些与对象逻辑状态无关的变量,比如用于记录函数调用次数等辅助信息。

代码示例

#include <iostream>

class MyClass {
private:
    int data;
    mutable int callCount;

public:
    MyClass(int value) : data(value), callCount(0) {}

    // const成员函数,不能修改非mutable成员变量
    int getData() const {
        callCount++;
        return data;
    }

    // 非const成员函数,可以修改成员变量
    void setData(int value) {
        data = value;
        callCount++;
    }
};

int main() {
    MyClass obj(10);
    const MyClass constObj(20);

    std::cout << "Non - const object getData: " << obj.getData() << std::endl;
    std::cout << "Non - const object callCount: " << obj.callCount << std::endl;

    std::cout << "Const object getData: " << constObj.getData() << std::endl;
    std::cout << "Const object callCount: " << constObj.callCount << std::endl;

    // 下面这行代码会报错,因为constObj是const对象,不能调用非const成员函数
    // constObj.setData(30);

    obj.setData(30);
    std::cout << "After setData, Non - const object getData: " << obj.getData() << std::endl;
    std::cout << "After setData, Non - const object callCount: " << obj.callCount << std::endl;

    return 0;
}

在上述代码中,MyClass类有一个data成员变量和一个mutable修饰的callCount成员变量。getData函数是一个const成员函数,它可以读取data,同时也能修改callCountsetData是非const成员函数,可以修改datacallCount。通过constObjobj的调用示例,展示了const对象对函数调用的限制以及mutable变量在const成员函数中的使用。