C++ objects that act like Java/C# objects.

S

Steven T. Hatton

I've had an idea kicking around in my head regarding how to create a library
of classes (templates?) that provide the same kind of functionality as do
Java classes which all derive from the UBC Object. There is no UBC in C++,
nor will there ever be one (well, there actually /is/ a UBC in C++, but it
is a pure abstraction). One feature of user defined Java classes is that
they all have a member derived from the java.lang.Class object. The Class
member object is part of what provides introspection. I haven't looked at
this in a couple years, so the details are a bit hazy for me. Another
aspect of Java classes is that all their member functions (AKA methods) are
actually objects (or at least can be represented as objects). A Method
object holds information such as the identifier and an array of Class
objects representing the parameter list. You can query a Java object at
runtime to determine its interface. You can also get its superclass (AKA
baseclass), etc.

C++ has objects that act like functions. Could a C++ class be created with
public function objects derived from a class called Function, and providing
the same functionality as the Java Method objects?

I don't know exactly how useful this would be, but it seems worth exploring
in view of the fact that both Java and C# have something like this as a
builtin language feature. One place where this is useful is actually at
design time. Classes are instantiated by the IDE, and queried for their
contents. For the functionality gained I don't believe you actually need
to use this approach. You could simply explore the class definition and
instantiate an IDE object representing the C++ class. AAMOF, KDevelop does
this to some extent.
 
A

Artie Gold

Steven said:
I've had an idea kicking around in my head regarding how to create a library
of classes (templates?) that provide the same kind of functionality as do
Java classes which all derive from the UBC Object. There is no UBC in C++,
nor will there ever be one (well, there actually /is/ a UBC in C++, but it
is a pure abstraction). One feature of user defined Java classes is that
they all have a member derived from the java.lang.Class object. The Class
member object is part of what provides introspection. I haven't looked at
this in a couple years, so the details are a bit hazy for me. Another
aspect of Java classes is that all their member functions (AKA methods) are
actually objects (or at least can be represented as objects). A Method
object holds information such as the identifier and an array of Class
objects representing the parameter list. You can query a Java object at
runtime to determine its interface. You can also get its superclass (AKA
baseclass), etc.

C++ has objects that act like functions. Could a C++ class be created with
public function objects derived from a class called Function, and providing
the same functionality as the Java Method objects?

I don't know exactly how useful this would be, but it seems worth exploring
in view of the fact that both Java and C# have something like this as a
builtin language feature. One place where this is useful is actually at
design time. Classes are instantiated by the IDE, and queried for their
contents. For the functionality gained I don't believe you actually need
to use this approach. You could simply explore the class definition and
instantiate an IDE object representing the C++ class. AAMOF, KDevelop does
this to some extent.

Hell, why not go all the way and have a full-fledged metaobject
protocol? And whipped cream!

To be serious, having such facilities comes at a cost -- and the cost in
this case runs very much contrary to what C++ is at its core, a
*systems* language, where the philosophy is "you only pay for it if you
use it".

Of course, at the same time, there's nothing stopping you from creating
your own class hierarchy with a base class that requires keeping such
information available -- but Greenspun's Tenth would soon obtain.

HTH,
--ag
 
S

Steven T. Hatton

Artie said:
Hell, why not go all the way and have a full-fledged metaobject
protocol? And whipped cream!

To be serious, having such facilities comes at a cost -- and the cost in
this case runs very much contrary to what C++ is at its core, a
*systems* language, where the philosophy is "you only pay for it if you
use it".

That's the core language design. Not a toolkit or library design. There
are classes with metaobject systems (I'll omit the term protocol until I
understand it better). Take for example Qt:

http://doc.trolltech.com/4.0/metaobjects.html

They use the CPP extensively to achieve their functionality most of their
classes do derive from QObject. Likewise for OSG and osg::Object.
Of course, at the same time, there's nothing stopping you from creating
your own class hierarchy with a base class that requires keeping such
information available -- but [explitive deleted]'s Tenth would soon
obtain.

I guess I'm missing your point. Since this is done to the exclusion of all
else in both Java and C#, and they are certainly viable, why would a
judicious mix of these heavier classes and concrete C++ classes present a
problem? Part of the slowness in Java apps is not due to inherent slowness
of Java, it's due to the design philosophy used by most Java programmers
unwaveringly. Java3D is pretty snappy.

There may actually be cases where this kind of design performs better than
traditional C++ designs. For instance, there may be more opportunity to
compose functions.

http://www.research.att.com/~bs/bs_faq.html#why
Why did you invent C++?
"I wanted to write efficient systems programs in the styles encouraged by
Simula67. To do that, I added facilities for better type checking, data
abstraction, and object-oriented programming to C. The particular projects
that prompted this work had to do with distributing operating system
facilities across a network. The more general aim was to design a language
in which I could write programs that were both efficient and elegant. Many
languages force you to choose between those two alternatives.

The specific tasks that caused me to start designing and implementing C++
(initially called "C with Classes") had to do with the design of a
distributed operating system."

Note well that the place where Java has most effectively competed with C++
is in distributed systems. EJB, etc.
 
D

Donovan Rebbechi

I've had an idea kicking around in my head regarding how to create a library
of classes (templates?) that provide the same kind of functionality as do
Java classes which all derive from the UBC Object. There is no UBC in C++,
nor will there ever be one (well, there actually /is/ a UBC in C++, but it
is a pure abstraction). One feature of user defined Java classes is that
they all have a member derived from the java.lang.Class object. The Class

This is part of a broad difference in design. Java is in a middle-ground
between an interpreted and compiled language. Basically, the runtime works
harder and the compiler does less. You can subvert the compile time type
checking in java and try to implement a more flexible runtime system, but
it's still going to be pretty spartan compared to the facilities offered by
a JVM (including JIT compilation for example) and you're probably forgoing
some of the benefits of the superior compile checking (e.g. using runtime
"stuff" when you could be using the powerful template system that java doesn't
have)
member object is part of what provides introspection. I haven't looked at
this in a couple years, so the details are a bit hazy for me. Another
aspect of Java classes is that all their member functions (AKA methods) are
actually objects (or at least can be represented as objects). A Method
object holds information such as the identifier and an array of Class
objects representing the parameter list. You can query a Java object at
runtime to determine its interface. You can also get its superclass (AKA
baseclass), etc.

Reminds me of the "asking personal questions of an object" anti-idiom: "do
you support the foo interface ? can you do X ? can you do Y ?". It's half a
step away from type-switching. I suppose there are cases where this is useful
(dynamically loading a prototype class and wanting to know which prototype
heirarchy to append it to would be one example) but I would bet on abuses
outnumbering uses. I'd bet on the legitimate uses having convenient
workarounds.

I know it's possible (arguably sometimes even desirable) to develop a toolkit
like Qt that makes C++ act like a bit like an interpreted language, but it's
also possible to hook up signals and slots without resorting to runtime type
checking. You can get looser coupling for free by either using an existing
framework that someone else has broken their back developing (e.g. Qt), or
just using interpreted languages instead of/in conjunction with C++ (which is
also ultimately a way of using a preexisting runtime object system -- the one
provided by the interpreted language API).

Cheers,
 
S

Steven T. Hatton

Donovan said:
This is part of a broad difference in design. Java is in a middle-ground
between an interpreted and compiled language.

I'd say it's more like a language compiled for an abstraction layer in the
sense of what Tannenbaum calls (IIRC) virtual machines.
Basically, the runtime works
harder and the compiler does less. You can subvert the compile time type
checking in java and try to implement a more flexible runtime system, but
it's still going to be pretty spartan compared to the facilities offered
by a JVM (including JIT compilation for example) and you're probably

Bear in mind, as I was recently reminded, there are now hard compilers for
Java. I haven't used them, and I don't know what they will do for you, but
they do exist.
forgoing some of the benefits of the superior compile checking (e.g. using
runtime "stuff" when you could be using the powerful template system that
java doesn't have)

It looks as though C++0X will have a lot of extended template support for
generic function objects. At least thats what I'm getting from looking at
TR1.
Reminds me of the "asking personal questions of an object" anti-idiom: "do
you support the foo interface ? can you do X ? can you do Y ?". It's half
a step away from type-switching. I suppose there are cases where this is
useful (dynamically loading a prototype class and wanting to know which
prototype heirarchy to append it to would be one example) but I would bet
on abuses outnumbering uses. I'd bet on the legitimate uses having
convenient workarounds.

It might be useful in visitor traversals such as scenegraphs. Such `query
for ability' functionality is already used in OSG.
I know it's possible (arguably sometimes even desirable) to develop a
toolkit like Qt that makes C++ act like a bit like an interpreted
language, but it's also possible to hook up signals and slots without
resorting to runtime type checking. You can get looser coupling for free
by either using an existing framework that someone else has broken their
back developing (e.g. Qt), or just using interpreted languages instead
of/in conjunction with C++ (which is also ultimately a way of using a
preexisting runtime object system -- the one provided by the interpreted
language API).

I'm not sure what the language being interpreted has to do with it.

The most useful exploitation of introspection I know of has to do with
development, and debugging. It's very easy to build a runtime class
browser that allows you to explore in detail the state of every object in
the program. For example when running a debugger. You can stop execution
at a breakpoint and visit every object as if it were part of a fancy
directory structure. You could probably do the same for C++, with a lot
more effort. I really wish KDevelop had a bit more clarity in its internal
design. I'd try to implement such support. As it stands, it's too
difficult to figure out how all the pieces fit together.
 
D

Donovan Rebbechi

I'd say it's more like a language compiled for an abstraction layer in the
sense of what Tannenbaum calls (IIRC) virtual machines.

Well it's that too -- but in terms of the spectrum of how hard the compiler
versus runtime works, it's middle-ground.
Bear in mind, as I was recently reminded, there are now hard compilers for
Java. I haven't used them, and I don't know what they will do for you, but
they do exist.

I don't expect them to catch on. (indeed if you're producing native code, are
you targeting a JVM ?) I think compilers that do things like runtime
optimisation are more likely to catch on, and more true to the philosophy of
the language.

[snip]
I'm not sure what the language being interpreted has to do with it.

Interpreted languages necessarily require these features, because the runtime
needs to be able to handle things like public inheritance, method lookup, etc,
at a language level (sure you can dynamically load in C++, but you're still
relying on the compile-time to build your derived class in the first place.)

Cheers,
 
A

Artie Gold

Steven said:
Artie Gold wrote:

[If you're going to quote my reply, you should include enough context to
indicate what I'm responding to.]
That's the core language design. Not a toolkit or library design. There
are classes with metaobject systems (I'll omit the term protocol until I
understand it better). Take for example Qt:

http://doc.trolltech.com/4.0/metaobjects.html

They use the CPP extensively to achieve their functionality most of their
classes do derive from QObject. Likewise for OSG and osg::Object.

Of course, at the same time, there's nothing stopping you from creating
your own class hierarchy with a base class that requires keeping such
information available -- but [explitive deleted]'s Tenth would soon

obtain.

[*NEVER* alter material that you quote from a previous respondent,
particularly if you're going to be insulting to a third party. And spell
it right.]
I guess I'm missing your point. Since this is done to the exclusion of all
else in both Java and C#, and they are certainly viable, why would a
judicious mix of these heavier classes and concrete C++ classes present a
problem? Part of the slowness in Java apps is not due to inherent slowness
of Java, it's due to the design philosophy used by most Java programmers
unwaveringly. Java3D is pretty snappy.

There may actually be cases where this kind of design performs better than
traditional C++ designs. For instance, there may be more opportunity to
compose functions.

Sure. Nothing in my argument has to do with what language or approach is
better. Different languages occupy different spaces, provide different
idioms, do different things well. Just because you *can* sharpen the
edge of a hammer, it doesn't mean that using it to cut is a good idea.
If you need a knife, use a knife!
http://www.research.att.com/~bs/bs_faq.html#why
Why did you invent C++?
"I wanted to write efficient systems programs in the styles encouraged by
Simula67. To do that, I added facilities for better type checking, data
abstraction, and object-oriented programming to C. The particular projects
that prompted this work had to do with distributing operating system
facilities across a network. The more general aim was to design a language
in which I could write programs that were both efficient and elegant. Many
languages force you to choose between those two alternatives.

The specific tasks that caused me to start designing and implementing C++
(initially called "C with Classes") had to do with the design of a
distributed operating system."

Note well that the place where Java has most effectively competed with C++
is in distributed systems. EJB, etc.

Erm, look at the quote again. Notice that it says "distributed
*operating* system". Different animal.

Cheers,
--ag
 
S

Steven T. Hatton

Artie said:
Steven T. Hatton wrote:

Sure. Nothing in my argument has to do with what language or approach is
better. Different languages occupy different spaces, provide different
idioms, do different things well. Just because you *can* sharpen the
edge of a hammer, it doesn't mean that using it to cut is a good idea.
If you need a knife, use a knife!

I believe you missed my point about composition closure objects. You could
not do that with normal member functions, though you may be able to with
function object class members. That would mean better performance than you
would get by using regular C++ member functions.

Arguments such as "this is not the design philosophy of C++", etc., are not
applicable to software built with C++. That is the design philosophy of
the language. It is meant to give the programmer the choice to implement
less efficient, but more useful and/or safer means of accomplishing tasks.

The argument that the proposed approach would carry an excessive burden
cannot be sustained as a general principle. There are many cases when the
kinds of performance enhancements gained by eliminating all virtual
functions (something you can do in Java as well) in a class are negligible
in comparison to what else is going on. Virtual inheritance is what is most
likely to be the biggest performance hit.

But pointers to member functions are not very efficient, and I'm not aware
of anybody suggestion I should avoid using mem_fun for that reason.
Erm, look at the quote again. Notice that it says "distributed
*operating* system". Different animal.

Cheers,
--ag

"Distributed operating system facilities". I'd say thread scheduling, file
transfer, file sharing, identity authorization and access control,
encryption, clustering, load balancing, RPC (remote procedure calls)
(remote method invocation or RMI in Java) etc., are distributed operating
system facilities. Also bear in mind that the concept of "a distributed
operating system" is really not where distributed computing has gone. Sure
there are distributed processing grids such as Beowulf clusters. Java
doesn't seem to have much of a role in that arena. But the kinds of
intersystem communications that merge several heterogeneous data sources
into a single coherent view, are definitely in Java's domain.
 
S

Steven T. Hatton

Donovan Rebbechi wrote:
[...]
Well it's that too -- but in terms of the spectrum of how hard the
compiler versus runtime works, it's middle-ground.

When assessing the impact of runtime overhead, it's important to consider
what operations are most likely to incur a substantial performance penalty.
For example, executing a simple for() loop to do basic math is probably
about the same for Java and C++. The cost of loading a class and/or
instantiating an object may be much higher in Java. Depending on what your
program is actually doing, such costs may be insignificant.

Also bear in mind that Java is something of a wrapper language around suff
written in C,C++, and perhaps even FORTRAN.
[...]
I don't expect them to catch on. (indeed if you're producing native code,
are you targeting a JVM ?) I think compilers that do things like runtime
optimisation are more likely to catch on, and more true to the philosophy
of the language.

On the philosophy part, I agree. As to whether they catch on? That really
is an unpredictable matter. One of the most interesting aspects of the GCJ
is that it supports null-pointer detection. At what runtime cost, I don't
know. That means that a C++ implementation could do the same.
[snip]
I'm not sure what the language being interpreted has to do with it.

Interpreted languages necessarily require these features, because the
runtime needs to be able to handle things like public inheritance, method
lookup, etc, at a language level (sure you can dynamically load in C++,
but you're still relying on the compile-time to build your derived class
in the first place.)

I'm not sure exactly what that means. Typically a derived class instance
has an internal subobject structure representing its base classes. How is
that significantly different from Java? The biggest performance cost I can
see with implementing a Java-style UBC design is that every class has to
have the equivalent of a vptr and vtbl. Since what I suggested does not
require every class to derive from a UBC, that is not an issue. OSG does
not derive such classes as Array and Vec3 from Object. These data classes
are much closer to the metal than structure classes such as Node.

One key motivation for suggesting any of this was to suggest that 'C++ could
do that too' if it's really all that useful. That implicitly begs the
question of whether the Java/C# design offers real value over C++ in some
areas. If it does, then 'C++ can do that too'. Or C++ can do that
*better*. That is, by exploring what functionality is actually gained from
the Java/C# design, it may be possible to implement the same functionality
with C++, but through templates or some other superior mechanism.

Had I continued learning Java and EJB, etc., I would be much further along
in having mainstream marketable skills than I now am with my limited C++
abilities. I really don't want to see C++ become marginalized. It should
be able to compete head-on with Java in the application server area.
That's not where I'm most interested in working, but it is where I have a
background. In order for that not to happen (more than it already has), C++
developers need to have some appreciation and understanding of what makes
Java attractive in that area.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top