class B
{
public:
void f(int) const
{
cout << "B.int" << endl;
}
void f(double) const
{
cout << "B.double" << endl;
}
};
class D: public B
{
public:
void f(void*) const
{
cout << "D.void" << endl;
}
};
int main()
{
D d;
d.f(0); //調用那個函數。
d.f(1); //調用那個函數。
d.f(0.1); //調用那個函數。
}
答案:3個調用全部調用子類的f(void*)。但由於後兩個不能轉換為void*,編譯出錯。void*是可以指向
任何類型的指標。C++中,只有int 0可以轉換為指標型,其餘均不可以,所以出錯。
關於子類函數對父類函數的覆蓋:
在C++類裡面,存在兩個概念,一個是重載,一個是覆蓋。
重載只是在類的內部存在,不會傳導到父類和子類中間。即便是一個函數聲明為virtual,也是這樣。
如果一個類,存在和父類相同的函數,那麼,這個類將會覆蓋其父類的方法,除非你在調用的時候,強制
轉換為父類類型,否則試圖對子類和父類做類似重載的調用是不能成功的。
class B
{
public:
void f(int i) const
{
printf("B::f(int):%d\n",i);
}
virtual void f(double d) const
{
printf("B::f(double):%f\n",d);
}
};
class D: public B
{
public:
void f(void* p) const
{
printf("B::f(void*):%x\n",p);
}
void f(int i) const{
printf("D::f(int):%d\n",i);
}
};
int main(int argc, char* argv[])
{
D d;
((B*)&d)->f(0); // 強制調用,否則父類的f(int)對子類不可見
d.f(1);
((B*)&d)->f(1); //
((B*)&d)->f(0.1); //
d.f(0.1); // warning: conversion from 'const double' to 'int', possible loss of data
d.f(NULL); // warning: converting NULL to non-pointer type
return 0;
}
運行結果:
B::f(int):0
D::f(int):1
B::f(int):1
B::f(double):0.100000
D::f(int):0
D::f(int):0
那麼,對於純虛函數呢,實際情況也是一樣的。例如
class X
{
public:
virtual void f(int) = 0;
};
class Y:public X
{
public:
virtual void f(int n)
{
printf("Y::f(int):%d\n",n);
}
virtual void f(double d)
{
printf("Y::f(double):%f\n",d);
}
};
class Z:public Y
{
public:
virtual void f(int n)
{
printf("Z:f(int):%d\n",n);
}
};
int main()
{
Z z;
z.f(1);
z.f(0.1);
}
運行結果:
Z:f(int):1
Z:f(int):0