当前位置:C++技术网 > 资讯 > C++重载:横向重载(静态重载)与纵向重载(动态重载)

C++重载:横向重载(静态重载)与纵向重载(动态重载)

更新时间:2015-06-23 13:26:19浏览次数:1+次

    经过大量的学习,对于C++的重载有了更进一步的理解,根据我的理解,分享给大家,给大家一个全新的认识。如果你还没有听过我说的这种说法,你还需要加深学习,如果你已经理解过了,你可以不用往下看了。
    曾经我对重载并不是很理解,直到后来,在一个学习资料上看到了一个词汇“纵向重载”。那时候我很意外,因为从没听说过所谓的“纵向重载”,也就更没有听说过“横向重载”。然后看了解释,似懂非懂。经过一段时间,慢慢的就想通了。现在就在这里分享给大家,帮助大家快速理解这个概念。
    在我们的一般的学习资料里,提到的重载,基本上指的是函数重载,也就是C++类中的成员函数的重载,重载需要满足的根本条件就是函数特征标。函数特征标就是参数列表,包括参数的个数和参数的类型以及参数的顺序。具体的重载要求可以参考资料,这里不做细致的描述。只要有任何一个条件不一样,比如顺序不一样,或者参数一个类型不一样,就构成了不同的特征标。而C++类中支持这种表示,也就是一个函数以同一个名字可以有很多种特征标的函数形式,这就是最开始接触的函数重载。然而,开始,一直以为重载就仅此而已。但是随着学习的深入,就接触到了“纵向重载”这一个概念,这也促使我进一步回头来审视之前的脑中的概念。
    后来发现,MFC中重载实在是太常见了,这就是所谓的虚函数的覆盖。原来也知道虚函数的覆盖。派生类只要将基类的虚函数完全一样的在派生类声明并实现,就实现了虚函数的覆盖。然后听到“纵向重载”,根据其解释,慢慢接受这种概念。后来仔细想想,是这么回事。只能说,我之前的理解太狭隘了。
    所谓重载,就是重复使用。而这个重复使用并不是反复使用同一个一模一样的东西,而是只是借用同一个名字而已。根据这个名字,根据不同的需求,提供不一样的功能。这就是重载。说一个例子,“父亲”这个词,其实是重载了的。如果你叫父亲,那是指你的父亲,而如果别人叫父亲,那是别人父亲。这也是一个重载。根据叫的人不同,也就是调用这个名称的对象不一样,产生的意义就不一样,这就是重载。所以,这里说的就是广义上的重载的概念。
    然后,我们再来分辨一下。在虚函数的覆盖这里,我们需要注意一个细节。如果基类的函数不提供虚拟函数标志,那么那个函数就不是虚函数。如果我们在派生类中同样的写了那个函数,一模一样的,这样能构成重载吗?根据上面的重载的解释,这里不能叫做重载,只是隐藏而已。指针是基类指针就调用基类的这个函数,如果是派生类的指针就永远调用派生类的函数。也就是说,在这里,这一个函数是由两个不同的指针来调用的,既然都是不同的指针的调用,那就是分开的,独立的,就没用重叠的地方,也就构不成重载。所以说,这种形式只是隐藏。或者理解成,基类和派生了只是有一个同名的函数而已,两个函数并无直接关系。只是,如果在派生类有这个函数,一般使用的是派生类的指针,我们在调用时就是派生类的这个函数,如果要调用基类的这个函数,我们需要显式的用基类类型的指针,是这个指针本来就是基类的,声明时就是基类类型,而不是指向基类。如果指针是派生类的,即使指向基类,也改变不了指针是派生类的这个特性,比如你是中国人,即使你一辈子居住在美国,你也改变不了你的血统。
    而函数的特征标不同,很自然的理解重载。根据上面的广义上的概念,我们再进一步理解。因为我们在调用这个重载函数的时候,我们都是用一个对象,只要使用了这个函数名,即可调用相应的函数。我们没有使用不同的语句来调用不同的版本的函数,都是使用一模一样的语句。也就是说,我们通过重载函数名,调用了,内部就执行了函数版本匹配,然后就成功了。所以这样可以说,重载其实是发生在调用的时候的一个概念。而虚函数覆盖,也是我们使用同一个指针,如果指向的是派生类,就调用派生类的函数,如果指向基类,就调用了基类的这个函数。我们的指针还是同一个,调用的函数名还是一个,调用函数的语句一模一样,然而,调用的结果就不一样了。这样,就跟一个类中的多种特征标的函数重载有了共同之处。总结一下,就是【通过同一个语句可以实现根据不同情况调用不同的函数】,普通的就是根据特征标进行情况区分,而虚函数则根据指针指向的类型。“通过同一个语句可以实现根据不同情况调用不同的函数”这一句就是重载的本质解释。这也是为什么能够将函数特征标形式和虚拟函数重载放在一起都叫做重载的原因。
    清楚了重载的本质分析,再来看看,“横向重载”和“纵向重载”的概念。函数特征标形式是在一个类中实现的多个函数版本,相当于在一个类中平铺多种形式,因此可以理解成横向(平铺)方式。而虚函数形式,是通过继承,构成一个垂直的关系。比如父亲跟儿子,属于两代人,是一个垂直的传递关系,父亲在上一层,儿子在下一层。也就是一个纵向的走向。C++中支持了虚拟函数,提供了重载虚函数的功能,因此就是我们说的“纵向重载”。
    将上述的两种方式的重载弄明白还不够,更应该树立一个广义的重载概念。因为重载还可能在其他地方以某种形式出现。只要细心留意你会发现的。欢迎分享交流。
    如果文中有不准确之处,请留言提出宝贵的建议,帮助我学习,虚心求教。