编程C++ 工程师

解释 C++ 中类成员函数的重载和默认参数是如何工作的。重载函数和默认参数值共同使用时有什么细微之处?

用 Hintsage AI 助手通过面试

答案。

函数重载(overloading)是声明多个同名函数的机制,但其签名(参数的数量或类型)不同。

默认参数值可以在函数声明中指定。细微之处:默认值只在调用的编译期间考虑,并由编译器根据可见的签名进行填充。

在类中常常出现这样的情况:

class Printer { void print(int n, char c = '*') { /* ... */ } void print(const std::string& s) { /* ... */ } }; Printer p; p.print(5); // 调用 print(int n, char c = '*'), c = '*' p.print("Hi"); // 调用 print(const std::string&)

细微之处:

  • 不应同时重载函数并仅通过默认参数值进行区分,这会导致歧义。
void foo(int x, int y = 10); void foo(int x); foo(1); // 错误:不清楚调用哪个函数

诱导性问题。

唯一允许在类成员函数上指定默认值的地方是哪里?

答案:类方法的默认值只能在类内的声明中指定(或在类外的首次声明中指定),而不能在类内和实现中都指定。否则会出现重新定义的错误。

class X { void func(int x = 5); // 可以在这里 }; void X::func(int x) { /* ... */ } // 但不能在这里!

由于不知道该主题的细微之处而导致的实际错误示例。


故事 1

银行软件在编译阶段发生故障:部分重载函数与不同的默认值干扰了对所需函数的明确选择,调用在编译阶段是歧义的——结果是无法在手动修正之前构建发布版本。


故事 2

团队中流行一种风格,即将所有默认值移至实现中,而不是类的头文件中,然而对于某些类方法,这导致接口与实现之间的不一致——不同的 TU 看到不同的函数参数,导致奇怪的编译和运行时错误。


故事 3

在扩展公共库时,错误地添加了重载同一参数但默认值不同的函数。编译器在 API 调用时开始产生歧义,而用户则遇到过时的调用和破坏的二进制兼容性。