首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

2012-03-23 
网上看到两段代码,非常迷惑,请高手指点一下!!代码1:#includeiostreamusing namespace stdclass base{pu

网上看到两段代码,非常迷惑,请高手指点一下!!
代码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),又何来改写呢?

热点排行