本文共 1703 字,大约阅读时间需要 5 分钟。
转载自:http://c.biancheng.net/cpp/biancheng/view/2996.html
从上节的例子可以看出,对象的内存模型中只保留了成员变量,除此之外没有任何其他信息,程序运行时不知道 obj 的类型为 Demo,也不知道它还有一个成员函数 display()。那么,究竟是如何通过对象调用成员函数的呢?
_
(不同的编译器有不同的实现),例如,func() 编译后为 func() 或 _func()。 而C++中的函数在编译时会根据命名空间、类、参数签名等信息进行重新命名,形成新的函数名。这个重命名的过程是通过一个特殊的算法来实现的,称为 名字编码(Name Mangling)。 Name Mangling 是一种可逆的算法,既可以通过现有函数名计算出新函数名,也可以通过新函数名逆向推演出原有函数名。 Name Mangling 可以确保新函数名的唯一性,只要命名空间、所属的类、参数签名等有一个不同,那么产生的新函数名也不同。 如果你希望看到经算法产生的新函数名,可以只声明而不定义函数,这样调用函数时就会产生链接错误,从报错信息中就可以看到。请看下面的代码: #includeusing namespace std; void display(); void display(int); namespace ns{ void display(); } class Demo{ public: void display(); }; int main(){ display(); display(1); ns::display(); Demo obj; obj.display(); return 0; }
__thiscall、cdecl 是函数调用方式,有兴趣的读者可以猛击《 》一文深入了解。除了函数,某些变量也会经 Name Mangling 算法产生新名字,不再赘述。
void Demo::display(){ cout<<
void new_function_name(const Demo *p){ //通过指针p来访问a、b cout<a< b<
new_function_name(&obj);这样就完成了对象和成员函数的关联,只不过与我们从表明上看到的相反,不是通过对象找函数,而是通过函数找对象。 这一切都是隐式完成的,对程序员来说完全透明,就好像这个额外的参数不存在一样。