On Java and C++

O

Oliver Wong

Jerry Coffin said:
[ ... ]
<Java>
class NodeToken {
public int beginColumn, endColumn;
}

class Token {
public int startColumn, endColumn;
}
</Java>

I'm trying to merge these two classes together. If they had used accessor
methods, I could have a methods setStartColumn(int) and
setBeginColumn(int)
affect the same private field, so that the changes would be seen by
either
interfaces.

This seems to be almost entirely orthogonal to the user
of accessor functions.
Unfortunately, they didn't use accessor methods, and instead
used public fields, so now I've got to start by adding the accessor
methods
to each seperate classes, mark the fields as deprecated, check for all
access to those fields, change those to invoke the accessor methods, then
merge the class, then simplify the API.

Well, in C++, you could pretty easily do something like
this:

class Mergedtoken {
public:
int beginColumn, endColumn;
int &startColumn;

MergedToken() : startColumn(beginColumn) {}
};

This produces essentially the same effect as you'd be
hoping to get via the accessor functions -- but without
the ugly syntax.

I'll admit I've never had to try this with Java, so I'm
not _sure_ its references will support this like C++
does, but offhand I can't think of any particularly good
reason they shouldn't.

Java doesn't have anything like what C++ calls "references". You can't
alias a variable in Java.

Also, to make things more interesting, the classes I'm trying to merge
actually keep track of something called "SpecialTokens". In one case,
they're implemented as a doubly-linked list, in another as a vector. The
Java code looks something like:

<Java>
class NodeToken {
public int beginColumn, endColumn;
public Vector<NodeToken> specials;
}

class Token {
public int startColumn, endColumn;
public Token nextSpecial, prevSpecial;
}
</Java>

So the problem again comes with two different representations for the
same ideas, and I can't simply take both fields, as their contents need to
be "synchronized" somehow.

- Oliver
 
N

Noah Roberts

Oliver said:
I'm going to avoid using the term "reference" and "pointer" in my
explanation here of Java's behaviour, and use a slightly different example
which will hopefully be more clear:

Integer a1 = new Integer(5);
Integer a2 = a1;

"a1", and "a2" are two different local variables which point to some
instance of Integer. They are both pointing to the same instance of Integer.
If, later on, you assign a different instance of Integer to "a1", "a2" will
still point to the old instance of Integer. So, for example, if you add the
following line:

a1 = new Integer(42);

then "a1" will now point to an Integer object which conceptually represents
the platonic concept of the number 42, while "a2" will still point to the
old Integer object which conceptually represents the platonic concept of the
number 5.

My understanding is that in C++, if you changed "a1" in that manner, and
if "a2" were a reference, then "a2" would also be updated to point to 42,
and not to 5.

Your misunderstanding is caused by your lack of acknowledgement that
Java hides references and has no such thing as "pointers".

Java:

A a = new A();
A a2 = a;

I now have two references to the same A but I cannot make a variable
that is a reference to the variable a.

Later changing a: a = new A(); as you said makes a and refer to
different data.

C++:

A a;
A & a2 = a;

a = new A() <- invalid.

a = A() <- rewrites the data a refers to. Actually calls a function
that assigns values...not a reference swap.

As you can see the syntax looks the same but the semantics are
completely different.

Lets change the C++ to be more equivelent with Java:

A * a = new A();
A * a2 = a;

Now assigning a a new value (a = new A() for instance) results in the
two pointing to different locations.

So I suppose you are right...Java and C++ references are
different...C++ references are more powerful:

class Y
{
A & a;
public:
Y(A & in) : a (in) {}
};

class Z
{
....same as Y
}

....
A a;
A a2;
Y y(a);
Z z(a);

a = a2;

a, Y::a, and Z::a now share the same data.

Java references are pointers without the benifits of being pointers and
without an explicit notation to label them as such to reduce confusion.
 
T

The Ghost In The Machine

In comp.lang.java.advocacy, Chris Smith
<[email protected]>
wrote
Bent C Dalager said:
The Ghost In The Machine wrote:

For its part Java has its own problems with arrays:

int[] s = new int[]{1,2,3};

Ick, and you say C++ has ugly syntax.

int s[] = {1, 2, 3};

This exact line will also work as expected in Java.

Yes, but it would be bad form in Java. Better to write:

int[] s = {1, 2, 3};

The fact that Java accepts a pseudo-C++ declaration syntax for arrays
for no good reason is not knowledge worth spreading. It was a mistake.

I do like the

int[] s

form; it's easier to find the type. :) Whether 1.6 will produce
copious warnings when encountering

int s[]

is an interesting question best directed at Sun, perhaps. :)
 
O

Oliver Wong

Noah Roberts said:
Java references are pointers without the benifits of being pointers and
without an explicit notation to label them as such to reduce confusion.

I actually laughed out loud when I read the above. That's very rare for
me. The punchline, that making Java more like C++ would *reduce* confusion,
was very unexpected.

Why would you need explicit notation to differentiate between Foo and
Bar if a given environment has only Foos and no Bars?

- Oliver
 
C

Chris Smith

Noah Roberts said:

Yes, really. I think perhaps you are misunderstanding the definition of
references in C++, actually. In C++, the declaration of a reference
does not create any kinds of new "thing" at all. It just creates a new
name, perhaps in a different scope from the original name, which means
exactly the same thing as the old name did.

Java has no such similar concept. Every time I write a declaration, a
new variable exists separately and independently of any other variable
in the application. Those variables may be "references" (by which
should be understood the C++ concept of a "pointer"), but two references
that are separately declared are separate and distinguishable from each
other, even if they point to the same object.

Don't let yourself get confused by thinking about what the compiler
might do. We're talking about languages here, not compilers. The
compiler is, of course, free to generate code to reserve memory in
response to a C++ reference declaration. For that matter, the compiler
is free to generate code to reserve memory in response to any source
code comment containing the word "orange". The language only specifies
the behavior, not how the compiler achieves that behavior.
Are you saying all of those a's are different in java? It has been
quite a while since I last used it but it seems to me that they are all
the same instance.

No, 'a' is not an instance of anything. No identifier can ever
designate an instance of anything. It can only designate a variable,
and a variable can only be a primitive or a reference. All of the a's
are different, even if they point to the same thing.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
O

Otis Bricker

class Y
{
A & a;
public:
Y(A & in) : a (in) {}
};

class Z
{
...same as Y
}

...
A a;
A a2;
Y y(a);
Z z(a);

a = a2;

a, Y::a, and Z::a now share the same data.

Java references are pointers without the benifits of being pointers and
without an explicit notation to label them as such to reduce confusion.

Since all references to Java Objects(not primatives sadly) are done the
same way, what reason is there for an explicit notation? Java programmers
know how they work. And they only work one way. That may be a limitation
but it hardly fosters confusion.

Yes, C++ references have many uses. Particularly 'const' ones. But they
also provide sources of confusion.
{
int i=10;
foo(i);
}

is i=10 still? C code yes, C++ maybe. In Java, there is no queston.

But are you are actually saying that having code like a=a2; silently
modify two other objects, z and y, is a reduction in confusion? Got to
love those hidden side effects!

OB
 
R

REH

WillemF said:
Most of the messages in this thread appear to be written by people who
only know one programming language.

Let's see, from the start...

BASIC (TRS-80, APPLE)
Machine (Z80)
Assembly (Z80)
Pascal (standard and USCD)
Fortran (IV and 77)
PILOT and LOGO (but they probably don't count!)
Lisp (good stuff!)
APL (some)
C
COBOL
RPG II
Modula-2
Prolog (very little)
Forth (a little)
Assembly (VAX)
C++
Assembly (8088, x86)
Visual BASIC (shutter)
Ada (83 & 95)
JOVIAL (a little)
Assembly (PPC)
Java
Perl

The order is blurry, and I've forgotten a lot over the years!

Then there are a spattering of things like SED, AWK, SQL, HTML, INFORM,
TADS, 4th gen. languages, etc.

REH
 
N

Noah Roberts

Otis said:
Since all references to Java Objects(not primatives sadly) are done the
same way, what reason is there for an explicit notation?

You just mention a difference right there in that sentance. In C++
primatives and objects act the same wrt value, pointer, and reference
semantics.

Java programmers
know how they work. And they only work one way.

They may behave the same but there is no explicit distinction between
when they are there and when they are not...it is implicitly based on
type.

That may be a limitation
but it hardly fosters confusion.

Might not be if it was true.
Yes, C++ references have many uses. Particularly 'const' ones. But they
also provide sources of confusion.
{
int i=10;
foo(i);
}

is i=10 still? C code yes, C++ maybe. In Java, there is no queston.

Sure there is, if i is an object and not a primative. Did Java change
i or not?

I don't know ... is there a way to implement the following signature in
Java? AFAIK there is not:

void foo(const I & i);

That function accepts a reference to an I object that cannot be changed
by foo without purposfully breaking the language's protections through
a const_cast. Callers can rely on the fact that i is not changed as
that definition is a statement to that effect.

I think the closest you could come to that behavior is to create an
"unmutable" interface for I objects and accept that interface instead
of I and then implement it for I. Of course this has to be done for
every different type of object you want to do this with...C++ contains
this interface within the class definition through the form of const
operations...a simple keyword that you place on functions that do not
alter the internals of the object...and the language won't let you do
it either unless you explicitly ask it to through casts or the mutable
keyword.

You can only do that if you have control over the I object and can
cause it to 'implement' an interface. Since your language doesn't
provide the idea of const as part of the language it isn't standard to
find interfaces implemented in those terms...in C++ it is. Either way
you have good vs. bad code and in the end can get the same thing done,
but C++ offers a little better way of doing it.

And off course interfaces are just a piss poor replacement for multiple
inheritance ;)

Also,

void foo(I i);

Is I changed? Certainly not in C++ where i is passed by _value_ no
matter what type it is...in Java you can't tell...someone may have
called a mutable function on it. In Java if i is an int it is copied
and the original is not changed...but if i is an object then maybe it
is, and maybe it isn't...you can't know from the signature alone.
But are you are actually saying that having code like a=a2; silently
modify two other objects, z and y, is a reduction in confusion? Got to
love those hidden side effects!

It is certainly not hidden and that was a sample only.
 
O

Otis Bricker

You just mention a difference right there in that sentance. In C++
primatives and objects act the same wrt value, pointer, and reference
semantics.

Actually they are very consistant. It is ALWAYS pass by value. It is
just that variables that hold Objects are always 'references'. Yuo you
are passing the value of the reference.

I said it was consistant. Not obvious.
Java programmers

They may behave the same but there is no explicit distinction between
when they are there and when they are not...it is implicitly based on
type.

And this is fully understood by any good Java programmer.
Might not be if it was true.

I don't know any halfway good java programmer that it confuses. I
couldprobaly find some butthen I could probaly find C++ programmers that
have trouble understanding references or const.
Sure there is, if i is an object and not a primative. Did Java change
i or not?

As all calls are by value, it cannot change i.
Had the code been
{
A a= new A();
foo(a);
}

a would also have not changed. It would still reference the same object.
But the actual object refered to by a might have changed.

I don't know ... is there a way to implement the following signature
in Java? AFAIK there is not:

void foo(const I & i);

I think you are right and I sometimes wish it were possible. And that
'i' was truly const.

But you seem to have missed my point. The calling code does not provide a
clue about the calling method. If someone changed the declaration of foo
(int i) to foo(int& i), my code is affected and my assumptions are no
longer valid. In Java, I KNOW that foo(a) might modify the object
referenced by 'a' if its an object but the reference will still point to
the same object. And that foo(int i) will not change anything.
That function accepts a reference to an I object that cannot be
changed by foo without purposfully breaking the language's protections
through a const_cast. Callers can rely on the fact that i is not
changed as that definition is a statement to that effect.

As I am primarily a C++ developer and have worked with the language for
close to 15 years, I am aware of those facts. But thank you. Some of the
Java folks may not know about it. Though you should see below since your
statement is a little too broad. Even ignoring 'mutable'. And I do like
and use 'mutable' to allow for logical rather than physical constness.
I think the closest you could come to that behavior is to create an
"unmutable" interface for I objects and accept that interface instead
of I and then implement it for I. Of course this has to be done for
every different type of object you want to do this with...C++ contains
this interface within the class definition through the form of const
operations...a simple keyword that you place on functions that do not
alter the internals of the object...and the language won't let you do
it either unless you explicitly ask it to through casts or the mutable
keyword.

You can only do that if you have control over the I object and can
cause it to 'implement' an interface. Since your language doesn't
provide the idea of const as part of the language it isn't standard to
find interfaces implemented in those terms...in C++ it is. Either way
you have good vs. bad code and in the end can get the same thing done,
but C++ offers a little better way of doing it.

Not sure why it has become my language. But thanks for the gift. Can I
collect royalties?

And const is not quite as const as you imply. Forgive the lack of
using/includes

class TestCase{
char*a;
public:
TestCase(){
a=new char('b');
}
~TestCase(){
delete a;
}
void dump(){
cout<<*a<<endl;
}
void morph()const{
*a='a';
}
};

void foo(const TestCase& t){
t.morph();
}



Const applies only to directly held objects. If you need to dynamically
allocate items, there are open to modification. As are non-const
references. So I cannot make TestCase::a point somepace else in morph or
foo but I can change the value that it points to.

And off course interfaces are just a piss poor replacement for
multiple inheritance ;)

MI is nice sometimes. But I often find it misused. Composition often
works better. Personally, I have found that NOT being able to use MI in
Java has often made me think more about composing objects/interfaces and
provided a better solution in the end. The same can and should be done
with C++ and I try. C++ does not prevent this. But I picked up the skill
working in Java as it was forced upon me. Languages shape out thinking.
Also,

void foo(I i);

Is I changed? Certainly not in C++ where i is passed by _value_ no
matter what type it is...in Java you can't tell...someone may have
called a mutable function on it. In Java if i is an int it is copied
and the original is not changed...but if i is an object then maybe it
is, and maybe it isn't...you can't know from the signature alone.

Actually, your example from before shows that i MIGHT change. At least
logically change.

class I{
int & handle;
public:
I(int& x):handle(x){};
void morph()const{
handle++;
}
void dump(){
cout<<handle<<endl;
}
};

void foo(I i){
i.morph();
}

I guess you could argue that it was the int& that changes. But clearly,
the state of the original i is not the same before and after that call.
It is certainly not hidden and that was a sample only.

Well, without looking through the definitions/implementations of Y and
Z, I would wave no way of knowing to expect this behaviour. And having
looked, I would have no way of knowing if that behaviour was changed in
the future. My code would still compile but the behaviour would change.
I call that hidden though you are free to use another term.

And yes, the same sort of bad code could be done in Java.

C++ is very flexible and powerful. I like working with it. But that does
not mean that Java is bad. It is different. As are Smalltalk and
Haskell. We should use them all to learn new ideas and understand the
craft better.


OB
 
T

The Ghost In The Machine

In comp.lang.java.advocacy, Noah Roberts
<[email protected]>
wrote
You just mention a difference right there in that sentance. In C++
primatives and objects act the same wrt value, pointer, and reference
semantics.

There are some languages that allow methods on primitives. Java,
sadly, is not one of them. :) (Neither is C++.)
They may behave the same but there is no explicit distinction between
when they are there and when they are not...it is implicitly based on
type.


Might not be if it was true.

I believe the newest version of C now allows references. However,
I'd have to look.
Sure there is, if i is an object and not a primative. Did Java change
i or not?

int is not an object. Integer is not mutable and is final.
If one uses something like HashMap, however, all sorts of
silliness can ensue.
I don't know ... is there a way to implement the following signature in
Java? AFAIK there is not:

void foo(const I & i);

That function accepts a reference to an I object that cannot be changed
by foo without purposfully breaking the language's protections through
a const_cast. Callers can rely on the fact that i is not changed as
that definition is a statement to that effect.

There is no elegant method to enforce constness in
an *object*. One can declare a parameter final but all
that does is preclude assignment within the code to that
parameter variable; the object is still mutable.

Hence hacks such as Collections.unmodifiableMap(Map).

One can attempt cloning of an object that there are a number of
issues there too, not the least of which is performance.

Also, the following cannot be done in Java, although one can
emulate them to some extent.

A & operator = (A const &);

Assignment operator.

A(A const &);

C++ Copy constructor, guaranteed to be called whenever needed.

~A();

Destructor. One can implement the finalize() method but one
cannot forcibly delete an object without some work -- the best
I can do is a forced garbage collection.

void * operator new(size_t);
void operator delete(void *);

Java has "one size fits all" memory allocation, though internally
one might see various perturbations, depending on the information
available to the compiler. Presumably the JVM has the option of
allocating an object on stack (for objects that never get exported
therefrom), or on the heap. However, I'd have to look.

void * operator new[](size_t);
void operator delete[](void *);

Arrays of objects in Java are little more than arrays of pointers.
In fact,

A a[] = new A[10];

a[5] = null;

is perfectly legal in Java; C++ would generate a compile time error.
I think the closest you could come to that behavior is to create an
"unmutable" interface for I objects and accept that interface instead
of I and then implement it for I.

That is a choice, yes. I'd say that's one of the better methods,
especially if one wants to create a Swing Bean. In that case,
one creates three items:

- the interface containing get/set methods and maybe some constants
- the data bean, which is little more than get/set stuff
- the Swing form, which is also get/set but instead of storing
data it stores into the widgets

A fourth and fifth interface can be optionally added; the fourth
interface would implement only the get() methods, the fifth the set().
The original interface would derive from *both* of them (Java allows
multiple inheritance of interfaces, as there's no "diamond problem").

A seventh object can be added for translation from and to a
recognized format, such as XML or JDBC, or one can split this
particular item into two pieces. Or one can use java.io.Serializable
or java.io.Externalizable.

At some point, one starts to get into overengineering territory. :)
Of course this has to be done for
every different type of object you want to do this with...C++ contains
this interface within the class definition through the form of const
operations...a simple keyword that you place on functions that do not
alter the internals of the object...and the language won't let you do
it either unless you explicitly ask it to through casts or the mutable
keyword.

Const can turn into a bit of a mess (mostly because if one
changes a parameter from (A &) to (A const &) in a routine
declaration, implementations tend to propagate the change
down) but at least it's allowed, and in fact in two places,
in C++:

A * p; // movable pointer to changeable value
A * const p; // fixed pointer to changeable value
const A * p; // movable pointer to unchangeable value
const A * const p; // fixed pointer to unchangeable value

Casting such as (A *) p is also possible but frowned upon;
one can also do const_cast<A *>(p), which is a little
easier to search for. The syntax can get a little ugly;
in fact, there's a utility for translating English-like
declarations to the C soup of (), [], and *.

In Java, one has four bad choices, if one is using a Map
or Set (for other classes, only the first is known to
be available; the second should work for Cloneable objects,
which fortunately includes HashMap and TreeMap -- beware,
however, as clone() is *protected*):

Map p = ...;

final Map q = p; // q cannot be assigned to but all
// methods such as q.put("a","b") are legal

final Map q = (Map) q.clone(); // q is a duplicate of p

final Map q = new TreeMap(p); // q is a duplicate of p,
// and not all classes support this sort of constructor

final Map q = Collections.unmodifiableMap(p); // q cannot
// be assigned to and q.put("a","b") throws an
// UnsupportedOperationException at runtime.
You can only do that if you have control over the I object and can
cause it to 'implement' an interface. Since your language doesn't
provide the idea of const as part of the language it isn't standard to
find interfaces implemented in those terms...in C++ it is. Either way
you have good vs. bad code and in the end can get the same thing done,
but C++ offers a little better way of doing it.

And off course interfaces are just a piss poor replacement for multiple
inheritance ;)

I don't particularly care for multiple inheritance, mostly because
of the "diamond problem". However, it can be useful, when
carefully managed. I prefer Java's solution here.
Also,

void foo(I i);

Is I changed? Certainly not in C++ where i is passed by _value_ no
matter what type it is...in Java you can't tell...someone may have
called a mutable function on it. In Java if i is an int it is copied
and the original is not changed...but if i is an object then maybe it
is, and maybe it isn't...you can't know from the signature alone.

Actually, one can, if the signature includes parameter types. Java's
blot, of course, is that int != Integer; the former is passed by value,
the latter by reference. (Of course for int and Integer it's a poor
example, since no one can modify an Integer anyway. However, other
classes, such as HashMap, are easily modified.)
It is certainly not hidden and that was a sample only.

The side effects problem is prevalent in both languages.
 
N

Noah Roberts

Otis said:
And this is fully understood by any good Java programmer.

Stupid argument. Any X language developer is aware of the quirks and
limitations of the language they use.
As all calls are by value, it cannot change i.
Had the code been
{
A a= new A();
foo(a);
}

a would also have not changed. It would still reference the same object.
But the actual object refered to by a might have changed.

You are purposfully skewing the discussion to match the point you are
trying to make...which is a pointless point anyway. The object the
variable a refers to changes if any mutable operations are performed on
it....you cannot stop it from happening or label if it will or not.
Stop playing with definitions and argue intelligently.

Point taken on the rest...
 
N

Noah Roberts

The said:
Const can turn into a bit of a mess (mostly because if one
changes a parameter from (A &) to (A const &) in a routine
declaration, implementations tend to propagate the change
down) but at least it's allowed,...

True, but such conditions indicate one of two things:

1) The object you are trying to make const should not be const because
you do in fact modify it in the code.

or

2) The functions you are calling in the code should have been const to
begin with.

In the case of 1 it is obvious that you are in error and the language
is telling you so...still, it will let you do it by using some casts to
get rid of constness and ignore the advice of the compiler.

In the case of 2 you are really just fixing bugs by propegating the
const chain.

This is a daily thing for me in certain legacy code I work on
actually...it was implemented poorly...I'm fixing it by adding const
where it belongs when I need to.
 
E

Ed Jensen

In comp.lang.c++ Noah Roberts said:
void foo(const I & i);

That function accepts a reference to an I object that cannot be changed
by foo without purposfully breaking the language's protections through
a const_cast. Callers can rely on the fact that i is not changed as
that definition is a statement to that effect.

Translation: The const "guarantee" can trivially be broken by casting
away const; thus, it's no real guarantee at all.
 
A

Andrew McDonagh

snipped nice post...

Noah, its important that you get Java's concept of variable and objects,
not being the same thing, if you want to try and map this to how C++
works.

Variables are more than names/alias but they aren't the object they
point to, they have the Type information of the object they point to at
most.
 
O

Otis Bricker

Stupid argument. Any X language developer is aware of the quirks and
limitations of the language they use.


So why are you so concerned that it is confusing? I am quite tempted to
adapt your insulting tone but "last refuge" and all.


You are purposfully skewing the discussion to match the point you are
trying to make...which is a pointless point anyway. The object the
variable a refers to changes if any mutable operations are performed
on it....you cannot stop it from happening or label if it will or not.
Stop playing with definitions and argue intelligently.

second time you choose to be insulting. All I was pointing out was that
is expected by Java developers. You seemed unable to recognize that.

Point taken on the rest...

I'm glad my stupidity and lack of intelligence didn't stop you from
getting something out of my comments.

From your hostile response, my contribution to the discussion seems to
be causing you some discomfort. Please feel free to stop responding.

I assure you I will. I cannot abide a lack of civility.

c.l.c++.m is more interesting than this anyway.

OB
 
L

Luc The Perverse

Otis Bricker said:
I don't know any halfway good java programmer that it confuses. I
couldprobaly find some butthen I could probaly find C++ programmers that
have trouble understanding references or const.

In java if you have made a linked list, worked with strings etc you will
know how the code works.

I remember trying to show my code to some "supposed" C++ programmers, and
everyone was confused by the notation, dereferencing, what was a variable,
what was an address etc.

So we have concluded that Java is easier to learn, more consistent, more
predictable. It is virtually impossible to hide what an object is (IE there
will never be a question as to if it is an pointer, reference or an object.)

Noah said earlier:
Java references, or whatever you call them behave EXACTLY like C++ pointers.
References in C++ are just pointers that are automatically dereferenced. (I
mean from a usage standpoint, if it is handled differently somehow in the
compiler I am not aware of it.)

So we concede on two points (except that they are the same point):
1. Java has no way of having a pointer to a primitive
2. Java has no way of having a pointer to pointer/reference

You refer to the inane inherent power of C++ notation, like some kind of
He-man crap. No one here is saying that C++ doesn't have more concise
methods of passing data around. What we are saying is that they add
complexity without adding significant value. In fact it has been my
personal experience that using things like references, and pointers to
pointers generally do nothing but obfuscate the code whether deliberate or
not.

Noah, you mentioned that when a function gets a class instantiation passed
in that it receives the object by value, as a copy - this way you can be
sure that no one is changing your object. IIRC in programming class I was
taught that a class wasn't supposed to have publicly accessible data
anyway - that everything was supposed to be accessed through a function -
unless it was from inside the same class (in which case we considered
transactions trusted.) This seems odd from seasoned professors if C++, the
language we were studying at the time, was immune to data corruption because
of passing by value. A poorly designed copy constructor, of which I have
seen many, can create ridiculous overhead, and corrupt data in a way that
genuinely confuses the programmer.

Where did you get it in your head that C++ needs to be better than Java
anyway? Can there be only one?

My points:
1. Regardless of inherent superiority C++ and Java exist independently, and
both sides have many satisfied users (and sometimes fanatics like you)
2. Yes, C++ semantics have inherent benefits. The problem isn't the
language, it is the users who don't understand and/or misuse them. Java
has been designed, deliberately, in such a way that misuse and confusion is
kept to a minimum. This seems to make everyone happy except you, because
you can't write your obfuscated piece of do nothing code whose functionality
could otherwise be represented in java, just not with the same
implementation.

If you want to argue the benefits of C++ against Java - you will find it has
already been done, but having no way to address a primitive or pointer is a
stale point - you are beating a dead horse. It doesn't help that many of
the things you are saying make no sense at all.
 
O

Otis Bricker

Noah, you mentioned that when a function gets a class instantiation
passed in that it receives the object by value, as a copy - this way
you can be sure that no one is changing your object. IIRC in
programming class I was taught that a class wasn't supposed to have
publicly accessible data anyway - that everything was supposed to be
accessed through a function - unless it was from inside the same class
(in which case we considered transactions trusted.) This seems odd
from seasoned professors if C++, the language we were studying at the
time, was immune to data corruption because of passing by value. A
poorly designed copy constructor, of which I have seen many, can
create ridiculous overhead, and corrupt data in a way that genuinely
confuses the programmer.

While I agree with most of what you said above and in the snipped part, I
think that is is unfairly presenting his view.

You might well have code such as( forgive the lack of detail):

Iterator i;

....

if( find(i,"fred") )
return "Fred's Here";
else if ( find(i,"Barney") )
return "Barney's Here";
else
return "Just us Girls";

By copying the Iterator, you do not have to preserve its original state.
That remains safely held in the original, outside the method call. It is
the copy that is changed by the code in find. And this happens regardless
of whether we are calling Iterator.getNextItem() or looking at member
variables.

OB
 
J

Jerry Coffin

@news.csolutions.net>,
(e-mail address removed) says...

[ ... ]
You refer to the inane inherent power of C++ notation, like some kind of
He-man crap. No one here is saying that C++ doesn't have more concise
methods of passing data around. What we are saying is that they add
complexity without adding significant value. In fact it has been my
personal experience that using things like references, and pointers to
pointers generally do nothing but obfuscate the code whether deliberate or
not.

I think there are two more or less separate things being
conflated here. It's true that C++ has separate notation
for pointers, references, etc. It's also true that the
separation of this notation rarely adds much (if
anything).

"...using things like references..." is a whole different
story. I have a hard time believing that anybody would
claim using references obfuscates code. Generally
references clean up code compared to using pointers.
Comparing to Java is difficult, simply because Java
doesn't really have a close analog to a C++ reference. In
addition, C++ references don't stand by themselves --
they're often (typically?) used in conjunction with other
things that have no analog in Java either.

I, for one, think that when used carefully the result can
be substantially cleaner than anything I've seen in Java
to do the same job, but it's hard to attribute that
entirely to references. In fact, the real improvement in
most cases comes from things like overloaded operators,
and references just happen to be more or less necessary
to do the job.

[ ... ]
2. Yes, C++ semantics have inherent benefits. The problem isn't the
language, it is the users who don't understand and/or misuse them. Java
has been designed, deliberately, in such a way that misuse and confusion is
kept to a minimum. This seems to make everyone happy except you, because
you can't write your obfuscated piece of do nothing code whose functionality
could otherwise be represented in java, just not with the same
implementation.

The previous example about merging classes does seem to
point out at least one situation in which Java makes a
job more difficult than the same job would be in C++. In
fairness, there is a tradeoff involved -- the necessary
capability is directly supported by C++, but no by Java.

In fairness, however, there are lots more tools to
support doing the job in Java. Some of these tools are
good enough that the amount of actual work for the
programmer is little or no greater using Java than C++.
In the other direction, these tools are hardly perfect
either -- at least of those I've tried, every one has had
at least a few things it supported poorly if at all.

At least IME, in most cases you're trading off one
complexity for another -- the language itself is simpler,
but instead you play with a half dozen different tools,
each with its own strengths and weaknesses.

Of the two basic directions, I know which _I_ prefer, but
I'm hardly conceited enough to think that means anybody
else should or will agree.
If you want to argue the benefits of C++ against Java - you will find it has
already been done, but having no way to address a primitive or pointer is a
stale point - you are beating a dead horse. It doesn't help that many of
the things you are saying make no sense at all.

This is, unfortunately, often true in both directions. At
least IMO, the problem is fairly simple: the strengths of
the two languages are sufficiently different that I think
it's difficult to come up with a comparison that doesn't
make the result of the comparison almost a foregone
conclusion. When they look competitive, it's usually at
doing something you'd probably never really do in
_either_ language. I'm not really interested in knowing
whether C++ or Java is worse at something that Lisp does
at least twice as well as either one!
 
T

The Ghost In The Machine

In comp.lang.java.advocacy, Noah Roberts
<[email protected]>
wrote
True, but such conditions indicate one of two things:

1) The object you are trying to make const should not be const because
you do in fact modify it in the code.

or

2) The functions you are calling in the code should have been const to
begin with.

In the case of 1 it is obvious that you are in error and the language
is telling you so...still, it will let you do it by using some casts to
get rid of constness and ignore the advice of the compiler.

In the case of 2 you are really just fixing bugs by propegating the
const chain.

This is a daily thing for me in certain legacy code I work on
actually...it was implemented poorly...I'm fixing it by adding const
where it belongs when I need to.

Yeah, well, not all of us can be perfect designers. ;-) I for one
routinely go back into my code and wonder how I could have written such
cruft and how asleep I was when I did so... :)
 
J

Jerry Coffin

My comment was largely based on language neutrality. I would rephrase
it to only cover languages that do not have other means of
accomplishing the same effect.

I think we're basically in agreement. You need some way
of getting code of your choice executed at the
appropriate times. From there it's a question of how
cleanly the language supports getting that done.
Data encapsulation is the goal. Trivial getX/setX accessors are a
means to reach that goal, and quite defensible in languages that
provide no other (better) means of getting there.

Here I disagree, at least with what you've said (though,
I suspect not with what you really think). Data
encapsulation isn't really the goal -- it's just a means
to an end. The real goal is cleaner code that's easier to
read, more maintainable, dependable, etc.
I need to add that in the context of the original suggestion (that
being able to directly access another object's state is wrong in
itself), your operator-based approach would be equally wrong, only
with a nicer syntax. It remains a poor man's approach to
encapsulation: Any algorithms that need to alter an object's state
should be internal to that object itself, not external to it.

In that context, yes. That's not the only framework
within which things make sense though -- at times, it
makes more sense to have classes that are little more
than containers, with the algorithms that apply to the
data being external.
According to this philosophy, you would never write
employee.wage *= 1.1;
You would write
employee.raiseWagePercent(10);

For that example, I completely agree.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top