MST
星途 面试题库

面试题:C++中const char *p与char * const p在类成员函数中的深入理解

定义一个C++类,类中有成员变量`char *str`。编写两个成员函数`void print1(const char *p)`和`void print2(char * const p)`,在这两个函数中都尝试修改类成员变量`str`。分析在编译和运行过程中可能出现的问题,解释原因,并说明如何正确处理以满足不同的需求(例如,一个函数只是读取成员变量,另一个函数需要修改成员变量)。
31.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 定义类及成员函数
#include <iostream>
#include <cstring>

class MyClass {
private:
    char *str;
public:
    MyClass() : str(nullptr) {}
    ~MyClass() {
        if (str) {
            delete[] str;
        }
    }
    void print1(const char *p) {
        // 这里p是const,不能通过p修改其指向内容,但可以修改类成员str
        if (str) {
            delete[] str;
        }
        str = new char[strlen(p) + 1];
        std::strcpy(str, p);
        std::cout << "print1: " << str << std::endl;
    }
    void print2(char * const p) {
        // p是指向const的指针,不能修改p的指向,但可以修改其指向的内容
        if (str) {
            delete[] str;
        }
        str = new char[strlen(p) + 1];
        std::strcpy(str, p);
        std::cout << "print2: " << str << std::endl;
    }
};
  1. 分析编译和运行问题及原因
    • 编译问题
      • print1函数中,pconst char*类型,意味着不能通过p修改其指向的内容。但该函数本身并没有尝试修改p指向的内容,而是对类成员变量str进行操作,所以编译不会因为pconst属性而报错。
      • print2函数中,pchar* const类型,表明p的指向不能改变,但可以修改p指向的内容。同样,该函数对p指向内容没有修改,而是操作类成员str,所以编译也不会报错。
    • 运行问题
      • 如果在使用类之前没有正确初始化str,直接在print1print2中尝试delete[] str会导致未定义行为,因为str可能是一个未初始化的指针。所以在使用delete[]之前需要先检查str是否为nullptr
  2. 正确处理以满足不同需求
    • 读取成员变量需求
      • 如果只是读取成员变量str,可以定义一个const成员函数,例如:
const char* getStr() const {
    return str;
}
- **修改成员变量需求**:
    - 像上述`print1`和`print2`函数,在修改`str`之前需要先释放其原有内存(如果存在),然后重新分配内存并复制新的内容。

这样可以确保在不同需求下,类的行为是安全且符合预期的。