题目

编写程序,演示同名函数针对不同类型(int、double、const char*)的重载逻辑。解释 C++ 编译器在底层如何通过名字修饰(Name Mangling)将函数签名编码为唯一样本符号;并使用 extern "C" 阻断符号修饰,以保证与 C 语言链接规范及动态链接库接口的绝对兼容。

输入格式:无需外部输入。

输出格式:依次输出各个重载函数与 extern "C" 函数的执行结果与符号机制说明。

数据范围与约定:编译器链接模型与跨语言符号互通。

思路与算法

1. 重载的编译期决议
函数重载依据参数个数、参数类型及 const 引用修饰进行静态决议,函数返回值类型不参与重载决议(仅靠返回值不同不能构成重载)。

2. Name Mangling 名字粉碎
C 语言符号名与函数名基本一致;C++ 编译器会将参数类型信息编码入最终符号名(如 _Z7displayi、_Z7displayd),使链接器在符号表中能够唯一寻址。

3. extern "C" 的核心使命
告诉 C++ 编译器按照纯 C 语言的规则生成符号表名(不执行名字粉碎),常用于 C++ 项目调用 C 标准库或将 C++ 函数暴露为外部 C ABI 供其他语言调用。

完整程序

#include <iostream>

// 1. C++ 风格重载函数群(编译器会生成不同的修饰名)
void printLog(int val) {
    std::cout << "[C++ 重载 - 整数]: " << val << "\n";
}

void printLog(double val) {
    std::cout << "[C++ 重载 - 浮点]: " << val << "\n";
}

void printLog(const char* val) {
    std::cout << "[C++ 重载 - 字符串]: " << val << "\n";
}

// 2. 采用 C 语言链接规范的函数(不可参与同名重载)
extern "C" void c_style_logger(int code) {
    std::cout << "[extern \"C\" 原生符号导出]: 错误码 = " << code << "\n";
}

int main() {
    std::cout << "--- 测试 C++ 名字修饰驱动的多态重载 ---\n";
    printLog(1024);
    printLog(3.14159);
    printLog("Hello Name Mangling!");

    std::cout << "\n--- 测试 C 语言链接规范导出 ---\n";
    c_style_logger(500);

    return 0;
}

运行示例

输出:

--- 测试 C++ 名字修饰驱动的多态重载 ---
[C++ 重载 - 整数]: 1024
[C++ 重载 - 浮点]: 3.14159
[C++ 重载 - 字符串]: Hello Name Mangling!

--- 测试 C 语言链接规范导出 ---
[extern "C" 原生符号导出]: 错误码 = 500