c与java覆盖重写的异同_关于java:覆盖C ++中的规则

从Java的角度来看,我惊讶地发现,您只能重写具有虚拟关键字的基本方法。在爪哇中,使用最后一个关键字声明无法重写的方法。

我脑子里有个想法,就是你很少想禁止凌驾于世,这样别人就可以根据自己的情况来扩展你的课程。

所以在C++中,如果你觉得某人可能想在某个阶段继承你的班级(也许几年后有人认为这是一个很酷的想法),你会让你的方法都是虚拟的吗?

或者是有一些重要的原因,想要禁止在C++中,我没有意识到这一点?

作为参考,这是我对每种语言所做的实验:

爪哇

public class Base {

void doSomething(){

System.out.println("Doing the base thing");

}

}

public class Derived extends Base {

void doSomething(){

System.out.println("Doing the derived thing");

}

public static void main(String... argv){

Base object = new Derived();

object.doSomething();

}

}

C++

class Base

{

public:

Base(void);

~Base(void);

virtual void doSomething();

};

void Base::doSomething(){

std::cout <

" << std::endl;

}

class Derived :

public Base

{

public:

Derived(void);

~Derived(void);

void doSomething();

};

void Derived::doSomething(){

std::cout <

}

int main(void){

Base * object = new Derived;

object->doSomething();

return 0;

}

何时将C++中的函数标记为虚拟的可能副本?

达菲莫和艾尔斯正把你带向正确的方向。我只是想对你说的一件事发表评论:

So in C++ if you feel that someone might want to at some stage inherit

from your class (maybe years later someone thinks its a cool idea) do

you make all your methods virtual?

从软件工程的角度来看:如果您没有立即使用继承,也没有使用接口,那么我不建议将方法声明为虚拟的。

虚拟方法带来了非常轻微的性能下降。对于非关键代码路径,性能影响可能可以忽略不计。但是对于经常被调用的类方法,它可以加起来。编译器不能做太多的内联和直接链接。相反,必须在运行时在v-table数组中查找要调用的虚拟方法。

当我的编码团队中有人开始与"稍后可能会有人想要…"进行设计对话时,我的"未来校对"反模式警报就会响起。设计可扩展性是一回事,但"面向未来的特性"应该推迟到那时。

此外,多年后那个认为这是一个很酷的想法的人,让他自己把类方法转换成虚拟的。不管怎么说,到那时你将进入更大的项目。:)

请注意,虚方法的性能命中仅适用于C++,或者如果实际上有不同的重写方法(甚至可以在优化中内联,等等)。

是的,你必须使你所有的方法都是虚拟的。

Java认为默认情况下一切都是公平的游戏,而禁止它需要采取行动。C++和C语言的观点截然相反。

是的,在C++中,一个类方法只能是EDOCX1×0,如果它在基类中被标记为EDCOX1×1。

如果您的类是为继承而创建的,并且您的类方法打算为基和派生提供不同的行为,那么将该方法标记为virtual。

良好阅读:

何时将C++中的函数标记为虚拟?

来自于虚函数缺省的语言的程序员往往会惊讶于C++具有逆向选择的默认值,即非虚拟是默认值。但是,请注意,[具体]虚拟函数的契约很难记录和测试,因为实际上涉及两个不同的契约:

所有覆盖函数的契约,即函数在概念上的作用。

具体功能发生作用的契约

只记录其中的一个并不能真正减少它,因为另一半根本不清楚。这也意味着您不能从具体的实现中瞥一眼实际的合同是什么(假设您处于一种不那么不典型的情况下,文档是由源提供的)。

举个例子,为什么所有的东西都是虚拟的或继承的可能不是一个很好的想法,实际上,经常会看到那些从EDCOX1 8继承的人,他们在爪哇并没有像他们想象的那样。

即使没有virtual也可以重写基类中的方法。

以这个小程序为例:

#include

struct A

{

void m()

{ std::cout <

"; }

virtual void n()

{ std::cout <

"; }

};

struct B : public A

{

void m()

{ std::cout <

"; }

virtual void n()

{ std::cout <

"; }

};

int main()

{

A a;

a.m();

a.n();

B b;

b.m();

b.n();

A &c = b;

c.m();

c.n();

}

程序输出为:

A

A

B

B

A

B

如您所见,方法B::m重写了A中的相同方法。但这只在使用B的精确实例时才有效。在第三种情况下,当使用对基类的引用时,需要virtual使其工作。

virtual关键字是overidding所必需的,或者你得到的是Function hiding关键字。派生结构B中的方法m()隐藏了基础结构A方法,而B中的方法n()覆盖了基础结构方法。

在B中对m()所做的操作称为重载(这也会导致基类版本被隐藏),而不是重写。在C++中,函数必须显式声明为虚拟函数,使其可重写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值