C++函数签名

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);       // 特化版本
  1. 链接与符号生成
    编译器根据签名生成唯一符号(如 _Z3addii 对应 add(int, int))。

undefined reference to symbol ‘ZN4zkos7service15ServiceSkeletonC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9’ 的函数签名是什么?

解析步骤:

  1. 分解修饰名:

    • _ZN 表示开始一个嵌套的名字。
    • 4zkos:长度为4的字符串 “zkos”,即命名空间 zkos。
    • 7service:长度为7的字符串 “service”,即命名空间 service。
    • 15ServiceSkeleton:长度为15的字符串 “ServiceSkeleton”,即类名。
    • C2:表示构造函数(基本构造函数,C1是完整构造函数,C2是基础构造函数,通常C2是实际构造函数的内部实现,但对外我们通常用C1)。
    • 后面的部分是参数列表。
  2. 参数部分:

    • ERK:表示第一个参数是常量引用(E表示扩展,R表示引用,K表示常量)。
    • NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:这是std::__cxx11::basic_string, std::allocator>的类型,即std::__cxx11::string(也就是C++11中的std::string)。
    • 然后我们看到有两个S9_:S9表示重复第9个类型(在Itanium C++ ABI中,S表示替换,9是索引)。实际上,这里表示后面的两个参数类型与第一个参数类型相同。

因此,整个函数签名是:
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的常量引用。

链接错误的原因可能是:

  1. 我们声明了这个构造函数,但没有定义(即没有实现)。
  2. 在链接时,我们使用了这个构造函数,但是对应的实现(在某个.cpp文件中)没有被编译或者没有链接到目标文件中。

解决方案:

  1. 检查是否在对应的.cpp文件中实现了这个构造函数。
  2. 检查链接时是否包含了实现该构造函数的源文件(或该源文件编译的目标文件)。
  3. 如果实现是在库中,检查是否链接了该库。

例如,在实现文件中应该有类似这样的代码:
zkos::service::ServiceSkeleton::ServiceSkeleton(const std::string& arg1, const std::string& arg2, const std::string& arg3) {
// 实现代码
}

或者使用委托构造等,但必须确保有定义。

你可能感兴趣的:(C++函数签名)