读书人

网上看到两段代码非常迷惑请一下!

发布时间: 2012-03-23 12:06:21 作者: rapoo

网上看到两段代码,非常迷惑,请高手指点一下!!
代码1:
#include<iostream>
using namespace std;

class base{
public:
virtual void test(){
cout << "base::test()" << endl;
}
virtual void test(double){
cout << "base::test(double)" << endl;
}
void test(int){
cout << "base::test(int)" << endl;
}
};

class derived : public base{
public:
void test(){
cout << "derived::test()" << endl;
}
//using base::test;
};

class A : public derived{
public:
void test(double){
cout << "A::test(double)" << endl;
}
};

int main(int argc, char **argv){
base *pb = new A;
pb->test(2.4);
return 0;
}
大家可以看到//using base::test;是注释的,此时derived中的test()函数将隐藏base类中的所有test函数(这一点你可以用derived *d = new derived; d->test(3.4)验证,绝对编译不通过,提示找不到这个重载函数),那么A再从derived继承,由于derived已经没有了virtual void test(double)函数,A中的void test(double)就不应该是virtual的了,那么pb->test(2.4)就应该调用base::test(2.4)才对啊,但是事实上输出A::test(double)" ,~~请高手解释一下啊!!将//using base::test;注释去掉输出A::test(double)倒是意料之中的事情~~
代码2:
#include<iostream>
#include<vector>
#include<fstream>
using namespace std;

template<class T>
void sort(vector<int>& data) //bubble sort
{
int count = data.size() ;
for ( int i = 0 ; i < count ; i++)
{
for ( int j = 1; j < count - i; j++)
{
if ( data[j] > data[j+1])
{

int temp = data[j] ;
data[j] = data[j+1] ;
data[j+1] = temp ;
}
}

}
}



void main()
{
ifstream in;
in.open("1.txt");
vector<int> a_v;
a_v.clear();
int a;
while(in >> a)
{
a_v.push_back(a);
}
sort(a_v);

}

当我把template<class T>注释之后编译就没有问题,而不注释时编译出错,注意红色的字是int 而不是 T!!!也就是说和这个template申明没有任何关系!!但是为啥编译结果会不一样呢??!请高手指点哪!!
小弟积分微薄,还请不吝赐教,感激不尽~~

[解决办法]
Derived隐藏基类的函数,只是说用Derived类型的指针或者Derived对象无法调用基类的函数而已。但是如果你用基类的指针去调用,就不再隐藏了,这也不会改变“虚函数”这种事实。楼主没有正确理解“隐藏”这个词的含义。

至于代码2,正是你强调的“注意红色的字是int 而不是 T!!!也就是说和这个template申明没有任何关系!!”导致了问题!模板在使用时,编译器必须能够根据参数推断出模板参数T的具体类型是什么,而因为你的参数列表和T其实无关,编译器没有任何办法能够推断出T是什么,当然就不行了
[解决办法]
Derived隐藏基类的函数,只是说用Derived类型的指针或者Derived对象无法调用基类的函数而已。但是如果你用基类的指针去调用,就不再隐藏了,这也不会改变“虚函数”这种事实。楼主没有正确理解“隐藏”这个词的含义。

至于代码2,正是你强调的“注意红色的字是int 而不是 T!!!也就是说和这个template申明没有任何关系!!”导致了问题!模板在使用时,编译器必须能够根据参数推断出模板参数T的具体类型是什么,而因为你的参数列表和T其实无关,编译器没有任何办法能够推断出T是什么,当然就不行了


一个是函数的隐藏一个是覆盖,是的,
[解决办法]

探讨
每一个对象有一个自己的虚函数表,既然A能够继承base的void test(double),那么derived也一定能够继承base的void test(double)了(否则就c++就具有跳过父类直接继承爷类的机制了....),那么derived为何不能访问void test(double)函数呢(别说是隐藏或是覆盖,我知道,但是请证明既然derived继承了base类的test(double)方法,而且与自身重写的test()编译器是完全可以区分的,为何derived的对象还不能访问test(double)方法??!!),如果不能证明这一点,那么说明derived根本没有继承test(double),A类的虚函数表就根本不会有test(double),又何来改写呢?

读书人网 >C++

热点推荐