C++函数签名-CSDN博客
函数签名的组成部分
函数名称
函数的名字(如 calculate、print)。
参数列表(Parameter List)
参数的类型、顺序和数量。
参数的名字 不影响 签名(如 int func(int a) 和 int func(int b) 是同一签名)。
所属的类或命名空间
成员函数属于特定类(如 MyClass::method)。
自由函数属于全局或某个命名空间。
成员函数的 const/volatile 限定
例如:void MyClass::method() const 和 void MyClass::method() 是不同签名。
noexcept 说明符(C++11起)
如 void func() noexcept 和 void func() 是不同签名。
引用限定符(C++11起)
如 void func() &(左值引用限定)和 void func() &&(右值引用限定)是不同签名。
不包含在函数签名中的内容
返回类型
例如:int func() 和 double func() 无法共存(编译器报错)。
默认参数
默认参数的值不影响签名,但影响函数调用时的行为。
异常规范(C++17 前)
如 throw()(C++17 后弃用,改用 noexcept)。
函数签名的作用
函数签名的重要性体现在函数重载和模板实例化中。在函数重载时,编译器使用函数签名来判断哪一个函数被调用;在模板实例化时,函数签名帮助确定具体实例化哪一个模板。
函数签名的作用
函数重载(Overloading)
通过不同签名区分同名函数:
int add(int a, int b); // 签名: add(int, int)
double add(double a, double b); // 签名: add(double, double)
模板特化
函数模板的特化依赖签名匹配:
template void func(T a); // 主模板
template<> void func(int a); // 特化版本
链接与符号生成
编译器根据签名生成唯一符号(如 _Z3addii
对应 add(int, int)
)。
undefined reference to symbol ‘ZN4zkos7service15ServiceSkeletonC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9’ 的函数签名是什么?
解析步骤:
分解修饰名:
参数部分:
因此,整个函数签名是:
zkos::service::ServiceSkeleton::ServiceSkeleton(const std::__cxx11::string&, const std::__cxx11::string&, const std::__cxx11::string&)
注意:C2表示这是构造函数的一个实现(可能是基础构造函数)。在链接时,我们通常只需要知道函数的签名,而不需要区分C1和C2(编译器会自动处理)。
所以,这个符号对应的构造函数是:
ServiceSkeleton(const std::string&, const std::string&, const std::string&)
这个构造函数有三个参数,都是std::string的常量引用。
链接错误的原因可能是:
解决方案:
例如,在实现文件中应该有类似这样的代码:
zkos::service::ServiceSkeleton::ServiceSkeleton(const std::string& arg1, const std::string& arg2, const std::string& arg3) {
// 实现代码
}
或者使用委托构造等,但必须确保有定义。