面试题答案
一键面试头文件声明类和实现文件定义类的作用
- 头文件声明类的作用
- 提供类的接口:头文件包含类的声明,它向其他代码模块展示了该类的结构,包括类的成员变量和成员函数的签名。其他源文件通过包含这个头文件,就可以知道如何使用这个类,例如创建类的对象,调用类的成员函数等。
- 实现代码复用:多个源文件可以包含同一个头文件,从而复用该类的接口信息,减少重复代码的编写。
- 实现文件定义类的作用
- 封装类的实现细节:实现文件包含类成员函数的具体定义,将类的实现细节与接口分离。这样,当类的实现发生变化时,只要接口不变(即头文件不变),使用该类的其他代码不需要重新编译,提高了代码的可维护性。
- 提高编译效率:如果把类的所有成员函数定义都放在头文件中,当一个源文件包含该头文件时,每次编译这个源文件,都要重新编译这些函数定义。而将成员函数定义放在实现文件中,只有实现文件本身需要编译这些函数定义,其他包含头文件的源文件编译时不需要重复编译函数体,加快了编译速度。
头文件中只声明类而不在其中定义成员函数的优点
- 减少编译依赖:如果在头文件中定义成员函数,当成员函数的实现改变时,所有包含该头文件的源文件都需要重新编译。而只在头文件中声明,实现放在实现文件中,只要头文件的接口不变,即使成员函数实现改变,其他源文件也无需重新编译,提高了编译效率。
- 增强代码的模块化和封装性:只在头文件中暴露类的接口,将实现细节隐藏在实现文件中,符合模块化编程和封装的思想。使用者只需要关心类的接口如何使用,而不必了解具体的实现过程,降低了代码的耦合度。
示例
假设我们有一个MyClass
类:
- 头文件
MyClass.h
// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
public:
// 声明成员函数
void printMessage();
};
#endif
- 实现文件
MyClass.cpp
// MyClass.cpp
#include "MyClass.h"
#include <iostream>
// 定义成员函数
void MyClass::printMessage() {
std::cout << "Hello from MyClass!" << std::endl;
}
- 使用类的源文件
main.cpp
// main.cpp
#include "MyClass.h"
int main() {
MyClass obj;
obj.printMessage();
return 0;
}
在这个例子中,main.cpp
只依赖MyClass.h
中的类声明,当MyClass.cpp
中printMessage
函数的实现改变时,只要MyClass.h
不变,main.cpp
不需要重新编译,体现了头文件只声明类而不在其中定义成员函数的优点。