C ++和Java对象模型之间的区别 [英] Differences between the C++ and the Java object model

查看:182
本文介绍了C ++和Java对象模型之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 在Java中,序列化对象非常容易。在C ++中,只有安全(?)到 memcpy 对象,只要它们像C structs(没有多态)。在C ++中,如果编译器能够生成默认(琐碎)复制构造函数,那么为什么它不能生成自动序列化的代码?


  2. 在Java中,只有静态函数和数据成员可以从ctor访问。在C ++中,我可以很高兴地使用来自ctor的非静态成员和函数。


  3. 在Java中,我可以初始化数据成员班上。在C ++中,这是一个编译错误。


  4. 在Java中,我可以在ctor中初始化 final 在C ++中,我必须对初始化列表中的 const 成员进行初始化。 在C ++中,当控件到达ctor的正文时,所有成员ctor都运行了,


  5. 可以调用另一个ctor。在C ++中,我们不能这样做。


  6. 在Java中, this 返回(引用的转义,多线程中的错误)。什么时候这个在C ++中有效? 这个可以在C ++和Java中轻松转义:在ctor (观察者模式)中注册一个尚未构造的对象到侦听器。 p>


  7. 在Java中,我不能在派生类中创建基类的私有函数。我很震惊,看到在C ++是好的,甚至有用。


任何人都可以给出这些差异的简短说明



更新。尝试收集答案到目前为止。


  1. Boost有一些类似序列化的支持。 (Tony)


  2. 即使我搞砸了这一点,Alf P. Steinbach给了一个有趣的例子。


  3. C ++ 0x将支持比C ++ 98更实用的初始化。 (Alf P. Steinbach)#3在C ++ 0x(Ken Bloom)中是合法的


  4. 在构造函数自己的类中声明的数据成员在构造函数的{body}开始执行时已经完全构建。 (C ++ -faq-lite)


  5. C ++ 0x将允许构造函数调用其他对等构造函数(Wikipedia,C ++ 0x)

    / li>
  6. C ++ 03考虑在其构造函数完成执行时构造的对象(维基百科)。


  7. 访问控制与对象模型无关:这是访问控制系统的一个功能,它是一个编译时功能。 (Yttrill)



解决方案


是很容易序列化对象。在C ++中,只要它们像C结构体(没有多态),它只对memcpy对象是安全的。


一个解释性语言(或者最近,作为BIT的意见,JIT编译),所以它别无选择,只能在运行时在程序中携带每个数据类型的元数据行李。在解释器,VM,可选编译器和元数据开销之间,Java程序需要大量内存。 C ++是一种编译语言,其中许多决策Java在编译时进行一次,元数据不用于解释以在运行时指导序列化。通常,即使在编译时,元数据也不会暴露,可能是因为不同的编译器供应商对程序进行了完全不同的建模,并且它们没有集体协商一个合适的表示。这也是相当大的工作。 Bjarne Stroustrup有一些关于如何暴露这样的信息的文件,但它甚至没有计划为C ++ 0x。


在Java中,我可以初始化数据成员内联,在类中。在C ++中,这是一个编译错误。


每个C ++构造函数都提供了一个完整的,如果值得的话,常见的构造步骤可以被考虑到支持例程中,但是对构造函数的调用仍然可见。不得不检查分散在类的各种任务将离域,虽然它当然可以方便。


在Java中,我可以在ctor中初始化最终成员。在C ++中,我必须在初始化列表中初始化const成员。


这反映了const成员被创建的想法它们的唯一值,并且不从一些不确定或空状态转换到初始化状态。


在Java中,ctor可以调用另一个ctor。在C ++中,我们不能这样做。


是的,有时在C ++中有点烦人 - 特别是对于需要在初始化列表,但您可以将其他常见构建步骤纳入支持函数。我认为C ++的位置反映了构造函数在构造基础,成员,指向虚拟分派表等的指针的工作 - 在机器代码级别不一定可以从另一个调用一个构造函数,并且只有正确的步骤执行。编译器可能需要生成第二个可调用的另一个构造函数版本,或内联调用构造函数的正确部分,但这是一种隐藏的膨胀。


在Java中,我不能在派生类中创建基类的私有函数。我很震惊地发现,在C ++是OK,甚至有用。


因为你承认这是有用的,也许Java应该添加它。 / p>


任何人都能给出这些差异的简短说明?



$ b b

好吧,我试过了。


  1. In Java it is very easy to serialize objects. In C++ it is only safe(?) to memcpy objects as long as they are like C structs (no polymorpism). In C++, if the compiler is able to generate the default (trivial) copy constructor then why can't it generate code for automatic serialization?

  2. In Java, only static functions and data members are reachable from the ctor. In C++ I can happily use the non-static members and functions from the ctor.

  3. In Java, I can initialize data members inline, in the class. In C++ it is a compile error.

  4. In Java I can initialize final members in the ctor. In C++ I have to do the initialization of the const members in the initialization list. In C++, when control reaches the body of the ctor, all the members ctor has run, right?

  5. In Java a ctor can call another ctor. In C++ we cannot do that.

  6. In Java, the this is not valid until after the ctor returns (escape of the this reference, a bug in multi-threading). When is this valid in C++? The this can easily escape both in C++ and in Java: registering a not yet constructed object to Listeners in the ctor (observer pattern).

  7. In Java, I cannot make a public function of the base class private in the derived class. I was shocked to see that in C++ is OK and even useful.

Could anyone give a short explanation for these differences?

Update. Trying to collect the answers got so far.

  1. Boost has some serialization-like support. (Tony)

  2. Even though I messed up this point, Alf P. Steinbach gave an interesting example.

  3. C++0x will support much more practical initialization than C++98. (Alf P. Steinbach) #3 will be legal in C++0x (Ken Bloom)

  4. The data members declared in the constructor's own class are guaranteed to have been fully constructed by the time the constructor's {body} starts executing. (c++-faq-lite)

  5. C++0x will allow constructors to call other peer constructors (Wikipedia, C++0x)

  6. C++03 considers an object to be constructed when its constructor finishes executing (Wikipedia).

  7. Things like access control have little to do with the object model: that's a feature of the access control system which is a compile time feature. (Yttrill)

解决方案

In Java it is very easy to serialize objects. In C++ it is only safe(?) to memcpy objects as long as they are like C structs (no polymorpism).

Java is an interpreted language (or more recently, as Billy comments, JIT compiled), so it has no choice but to carry around metadata baggage of every data type in the program at run time. Between the interpreter, VM, optional compiler and metadata overheads, Java programs need a lot of memory. C++ is a compiled language, where many of the decision Java makes are made once at compile time, and the metadata isn't around for interpretation to guide serialisation at run-time. In general, the metadata isn't exposed even at compile time, probably because different compiler vendors model the program quite differently, and they haven't collectively negotiated a suitable representation. It's also considerable work. Bjarne Stroustrup has some papers on how to expose such information, but it's not even planned for C++0x. Meanwhile, with a little manual markup C++ programs can serialise objects - see boost for a good implementation.

In Java, I can initialize data members inline, in the class. In C++ it is a compile error.

Each C++ constructor provides a complete, independent view of how the object will be initialised. If worthwhile, common construction steps can be factored into a support routine, but the call to that is still visible in the constructor. Having to inspect various assignments scattered through the class would delocalise that, though it can certainly be convenient. Much of a muchness here, I'd hazard.

In Java I can initialize final members in the ctor. In C++ I have to do the initialization of the const members in the initialization list.

This reflects the idea that const members are created with their one and only value, and do not transition from some indeterminate or null state to an initialised state.

In Java a ctor can call another ctor. In C++ we cannot do that.

Yes, it's a little annoying in C++ sometimes - particularly for references and consts that need to be in the initialiser list, but you can factor other common construction steps into a support function. I think C++'s position reflects the job of a constructor in constructing bases, members, pointers to virtual dispatch tables etc. - it's not necessarily possible at the machine code level to call into one constructor from another and have just the right steps execute. The compiler could be required to generate a second callable-from-another-constructor version, or inline the right parts of the called constructor, but that's kind of hidden bloat.

In Java, I cannot make a public function of the base class private in the derived class. I was shocked to see that in C++ is OK and even useful.

Given you acknowledge it's useful, maybe Java should add it.

Could anyone give a short explanation for these differences?

Well, I tried.

这篇关于C ++和Java对象模型之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆