您的位置:首页 > 编程语言 > C语言/C++

从全局函数与成员函数区别来探讨c++深层原理

2010-04-14 15:07 232 查看
对一门语言来说,函数是个执行单元,如果,你想让你系统更加清晰,具有扩充性,对函数相关参数的定义是必不可少的,而影响这个结果还有我们对语言中函数的理解度。
在c++中函数一般为:全局函数和类成员函数。他们的区别在与调用方式和编译对其的处理不同。在这里,我们必须把这个概念根深蒂固:任何编译给我们提供一种语法,我们按照这个语法来编写程序,编译器根据这个语法来翻译程序,最终变成机器指令。我们知道,计算机就是不一条一条地在执行指令。

我们知道,编译器会将我们的代码翻译成相应的机器指令,而他在我们进行函数调用时,会就很多其他的事情: 传参数,传this,也正是这些,来改变我们的编程思想。怎么理解这句话?
编译器遇到全局函数和类成员函数的处理是不是相同,很显然是不同,首先,他规定了不同的调用方法。成员方法需要用一个实例来调用,这样的做的方法是因为成员函数需要传入this(对象指针),理解这点,我想你会对很多问题有比较深的看法。
类成员方法有个默认的输入参数,就是该对象的一个指针。在c++中你调用一个成员函数有两中方法:1.实例化一个对象:A a;2.定义一个该类的指针并new()。 而全局函数就可以用::。这个限制是编译器给你的。我们知道,函数名就是一个地址,如:
Void show(){cout<<”show”<<endl;}
编译器在遇到show()时,就知道这是个函数调用,并在把show()函数的首地址放入ip中。并且做一些准备,为调用这个函数。所以,我们要是得到这个地址,并也告诉编译器这个地址是个函数地址,当我执行这个地址时,编译器自然也会去执行我们的函数,这样我们就可以执行类的私有成员函数了,如果理解了点,你就会把工作区分的很清除了,了解编译器的本质了。最能说明这个问题的是函数的虚拟表了。
这里,就来探讨下this指针的本质以及编译器用他来完成的动态编译(多态性)。看下面这段普通的代码:
#include<iostream>
using namespace std;
class A{public:
virtual void show()
{cout<<”A is show”<<endl;}
};
class B:public A
{public:void show(){cout<<”B is show”<<endl;}}
int main(){
A * a;
B b;
a=&b;a->show();}
我们知道结果是B is show;也知道这是因为c++的多态机制造成了,但说完这些,你还能说些东西关于这个程序吗?你能大约描叙这个程序对应机器码吗?如果,不能这说明你对c++的多态还不是很了解,这样是很少在高层设计上灵活运用的。
上面说过,调用成员函数的两种方法,这属于第二种,a是个指针,是个A类型的,所以,你用他去调用show()方法,编译器是让过的,因为他发现你在A里面有show()这个方法,但当他发现这是个virtual 函数,所以,他就要得到此时调用这个函数的this指针。A的值是一个B对象的地址,很显然编译器用的也就是B的虚拟表了。而B的虚拟表是有show()方法的,所以,编译器在给我们翻译时就是按这个过程来的,而b的位置要运行时才可以确定,所以叫动态编译。
上面这个分析,至少可以让我们回忆和解释以下我们熟知的知识点:
1. 用c++多态的方法和调用格式。
2. 父类中必须要有这个方法(否则,编译器不让过:编译器错误,原因是不符合成员函数调用规则),子类必须要覆盖这个方法(否则,调用的是父类方法:运行错误,原因b的虚拟表还是A的虚拟表信息)。
3. this指针是作为一个参数传入的,这里可以看出this指针的重要性,虽然,他对程序员是隐藏的,但只要我们认真想想这些基本问题,我们就会无时无刻地看到他。也正是因为他,才让函数找到了数据。为什么在函数里面可以直接调用本类的函数?也是因为他,因为编译器将在函数内部,不管是直接访问的变量还是方法都加上个this,这就就可以访问到成员变量,而函数访问也符合前面的要求。
假若,你真的理解上面的,我相信,你将会在各种高层的设计模式中跳转自如,而不会偏离航线,也只有理解这些,你才能设计出完美的程序结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐