子类函数对父类同名函数的覆盖
2008-09-18 22:46
218 查看
先看一道题:
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可以转换为指针型,其余均不可以,所以出错。
关于子类函数对父类函数的覆盖:
(引用http://hi.csdn.net/doon的发言)
在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
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可以转换为指针型,其余均不可以,所以出错。
关于子类函数对父类函数的覆盖:
(引用http://hi.csdn.net/doon的发言)
在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
相关文章推荐
- C++ 子类函数对父类同名函数的覆盖
- C++子类调用父类覆盖的函数
- java注解,在继承时会被子类覆盖,会被子类覆盖的函数覆盖,如果继承的子类不写注解的话,默认没有注解,即不会继承父类的注解
- C++父类子类间函数重定义,虚函数重写(覆盖)以及重载
- java中函数覆盖(即重写override),子类的返回类型一定要和父类一样吗?
- Java、C++中子类对父类函数覆盖的可访问性缩小的区别介绍
- c++父类虚函数被子类虚函数覆盖后,如何直接调用父类的虚函数?
- 【C++】子类在重写虚函数时,会覆盖父类的函数
- c++子类和父类成员函数重名
- 子类调用父类中的覆盖的方法
- 在子类中调用父类被隐藏的函数的方法
- 匿名子类调用父类成员函数on_Previous();
- 子父类中的变量,函数,构造函数的特点以及子类的实例化过程
- C++子类对象隐藏了父类的同名成员函数(隐藏篇)
- 父类和子类属性覆盖的各种情况分析
- 重写(覆盖)子类的权限不能低于父类的权限
- 虚函数的特点就是执行的时候会下降到子类去执行同名覆盖函数 good
- C++中指向子类的父类指针访问父、子类成员时的权限和函数隐藏规则
- c++子类继承父类的覆盖问题
- 在多继承的时候,如果一个类继承同时继承自class A和class B,而class A和B中都有一个函数叫foo(),如何明确的在子类中指出override哪个父类的foo()?