关于子类重写父类私有虚函数
来源:互联网 发布:nginx filter 编辑:程序博客网 时间:2024/06/05 05:04
私有的虚函数,子类能重写么?
编译器在编译private virtual时却似乎将关键字private忘记了,它们的偏移地址都毫无例外的存放在了子类的VTABLE中!
这就是破绽!你可以在之类声明一个同名的public函数.编译器此时会把该函数当做重写父类虚函数对待.
1,编译器不检查虚函数的各类属性.
2,编译器在编译子类成员函数时,会先查询父类,如果存在非虚函数,则隐藏父类函数.如果存在虚函数,则重写该位置的虚函数.此时你又可以赋予该函数在该类中的各种属性(例如public).
在看代码的时候出现这种情况
class Base
{
private:
virtual void why()=0;
};
class Drive_first : public Base
{
public:
virtual void why(){do something};
};
我们知道基类如果有纯虚函数,子类继承的时候需要重写掉她,可是这种情况算不算重写掉基类的why()函数?
其实我最想知道的是在什么样的设计思想下趋势出来了这种代码?
是为了基类的抽象性么?
是重写,虚函数的查找是根据虚函数表来的,虚函数表不管什么private和public ,也就是说虚函数没有进行权限控制?
为了提供更为强健的基类接口.
基类中的接口一般一个非虚的普通函数,其内部实现通过调用一个私有虚函数来实现.子类可以改写该私有虚函数,而不会理会公有的接口.
有点类似 template method
所谓private方法,是不作为对外访问接口的。
比如下面的类层次结构,黑人和白人发音的方式不同,导致他们唱歌方式不同,但是对外接口只有唱歌:
class people{
public:
virtual void sing()=0;
private:
virtual void sound()=0;
};
class white:public people{
public:
void sing(){sound();}
private:
void sound(){}
};
class black:public people{
public:
void sing(){sound();}
private:
void sound(){}
};
私有只是让子类不能访问父类,仅此而已,对其他规则没限制,也就是说那是重写。
其实我最想知道的是在什么样的设计思想下趋势出来了这种代码? 是为了基类的抽象性么?
-----
我觉得并不是为了基类的抽象性,因为纯虚函数已经可以描述抽象性了,比如Java中的接口在C++中就可以通过只包含纯虚函数的类来模拟。
具体这样做的目的我也不是太清楚,但是我们分析一下这样做的后果,看看能不能反推出这样做的目的(或者是无目的的)
1.纯虚函数的设计说明这个类是个抽象基类,派生类必须重写(或者说实现)这个纯虚函数才可能被实例话,否则派生类仍然是个抽象基类。
2.将纯虚函数设为private,说明这个纯虚函数并不是一个接口函数,外界不能通过抽象基类指针直接调用。
由此可以想像,这个私有纯虚函数可能是为公共接口服务的。
说简单一点,就是在父类中还不确定一个函数要实现什么功能(但是这个函数又是必须的),在子类中再具体说明他需要实现的功能,就可以使用纯虚函数。比如一个人需要运动,但是运动的方式很多,就可以先在父类设置一个纯虚函数VIRTUAL VOID SPORT()=0,在子类中就可以具体说明SPORT的方式。
为了提供更为强健的基类接口. 更高层次的抽象?
基类中的接口一般一个非虚的普通函数,其内部实现通过调用一个私有虚函数来实现.子类可以改写该私有虚函数,而不会理会公有的接口.
有点类似 template method
呵呵,,大家分析的都很正确啊!!谢谢你们了!
以后可以这么设计了
class people
{
public:
inline void sing()
{song()};
private:
virtual void song()=0;
};
class white : public people
{
public:
void song()
{white people song}
};
class black : public people
{
public:
void song()
{black people song};
};
这样的话只需要重写自己的那部分,然后根据不同对象的调用来执行各自的song()函数
编译器在编译private virtual时却似乎将关键字private忘记了,它们的偏移地址都毫无例外的存放在了子类的VTABLE中!
这就是破绽!你可以在之类声明一个同名的public函数.编译器此时会把该函数当做重写父类虚函数对待.
1,编译器不检查虚函数的各类属性.
2,编译器在编译子类成员函数时,会先查询父类,如果存在非虚函数,则隐藏父类函数.如果存在虚函数,则重写该位置的虚函数.此时你又可以赋予该函数在该类中的各种属性(例如public).
在看代码的时候出现这种情况
class Base
{
private:
virtual void why()=0;
};
class Drive_first : public Base
{
public:
virtual void why(){do something};
};
我们知道基类如果有纯虚函数,子类继承的时候需要重写掉她,可是这种情况算不算重写掉基类的why()函数?
其实我最想知道的是在什么样的设计思想下趋势出来了这种代码?
是为了基类的抽象性么?
是重写,虚函数的查找是根据虚函数表来的,虚函数表不管什么private和public ,也就是说虚函数没有进行权限控制?
为了提供更为强健的基类接口.
基类中的接口一般一个非虚的普通函数,其内部实现通过调用一个私有虚函数来实现.子类可以改写该私有虚函数,而不会理会公有的接口.
有点类似 template method
所谓private方法,是不作为对外访问接口的。
比如下面的类层次结构,黑人和白人发音的方式不同,导致他们唱歌方式不同,但是对外接口只有唱歌:
class people{
public:
virtual void sing()=0;
private:
virtual void sound()=0;
};
class white:public people{
public:
void sing(){sound();}
private:
void sound(){}
};
class black:public people{
public:
void sing(){sound();}
private:
void sound(){}
};
私有只是让子类不能访问父类,仅此而已,对其他规则没限制,也就是说那是重写。
其实我最想知道的是在什么样的设计思想下趋势出来了这种代码? 是为了基类的抽象性么?
-----
我觉得并不是为了基类的抽象性,因为纯虚函数已经可以描述抽象性了,比如Java中的接口在C++中就可以通过只包含纯虚函数的类来模拟。
具体这样做的目的我也不是太清楚,但是我们分析一下这样做的后果,看看能不能反推出这样做的目的(或者是无目的的)
1.纯虚函数的设计说明这个类是个抽象基类,派生类必须重写(或者说实现)这个纯虚函数才可能被实例话,否则派生类仍然是个抽象基类。
2.将纯虚函数设为private,说明这个纯虚函数并不是一个接口函数,外界不能通过抽象基类指针直接调用。
由此可以想像,这个私有纯虚函数可能是为公共接口服务的。
说简单一点,就是在父类中还不确定一个函数要实现什么功能(但是这个函数又是必须的),在子类中再具体说明他需要实现的功能,就可以使用纯虚函数。比如一个人需要运动,但是运动的方式很多,就可以先在父类设置一个纯虚函数VIRTUAL VOID SPORT()=0,在子类中就可以具体说明SPORT的方式。
为了提供更为强健的基类接口. 更高层次的抽象?
基类中的接口一般一个非虚的普通函数,其内部实现通过调用一个私有虚函数来实现.子类可以改写该私有虚函数,而不会理会公有的接口.
有点类似 template method
呵呵,,大家分析的都很正确啊!!谢谢你们了!
以后可以这么设计了
class people
{
public:
inline void sing()
{song()};
private:
virtual void song()=0;
};
class white : public people
{
public:
void song()
{white people song}
};
class black : public people
{
public:
void song()
{black people song};
};
这样的话只需要重写自己的那部分,然后根据不同对象的调用来执行各自的song()函数
- 关于子类重写父类私有虚函数
- PHP支持 子类重写父类的 私有方法?
- 关于子类重写父类方法override
- 子类重写父类的构造函数
- 关于Java子类访问父类的私有变量
- C++从子类访问父类的私有函数
- C++从子类访问父类的私有函数
- 从子类访问父类的私有函数
- C++:从子类访问父类的私有函数
- 子类使用构造函数初始化父类的私有数据
- 子类重写父类的虚函数后需要调用父类的虚函数
- 子类继承父类,重写纯虚函数和虚函数时注意
- 【C++】子类在重写虚函数时,会覆盖父类的函数
- C++父类子类间函数重定义,虚函数重写(覆盖)以及重载
- C++父类子类间函数重定义,虚函数重写(覆盖)以及重载
- 基类私有虚函数可被派生类重写
- C++ 继承中子类与父类虚函数入栈顺序 及父类私有虚函数的调用方式
- 子类继承父类的私有属性
- redhat linux在虚拟机中配置tftp的方法
- Svn安装与使用
- C语言中的const,volatile与restrict的使用
- Oracle 数据泵的使用(1)
- CRC原理与计算
- 关于子类重写父类私有虚函数
- maven 编译hadoop错误解决
- RHEL下安装mysql 5.5
- UIWebView / NSURL / NSBoundle 相关应用 (实例,加载完成前的背景, 默认safari打开链接地址等)
- 50A_Domino piling
- equals()和hashcode()用法
- 网易视频播放器
- 素数判定
- ubuntu 安装maven