to get an objects position, safe in the knowledge that who ever is calling the method can't tinker with the returned object. All well and good. But the Java equivilent would be without any sort of 'const' modifier, and so open up the class to be modified in an unintended way, bypassing the intended set method.

'final' to the best of my knowledge, just makes the reference final, not the actual data, and is therefore not a substiture. So the alternative would be

1

voidgetPosition(Vector2fdest);

and having a blank object into which the new information is copied. That or return a copy, but both of these need an extra object to be created just to hold what will likely be a temporary result.

Now I may be being overly paranoid about the GC, but this is getting to be really annoying. I don't like possibly creating hundreds of tiny little objects per frame, and the alternative of keeping them around (or a small number of temporary ones around and reusing them) gets ugly when used to any large extent.

You're returning your vector truncated as the immutable base class. Only you can (honestly) alter it. You could take it one step further and make MutableVector2F a private class of your class.

That offers the same protection as C++ does, generally. It prevents honest use of your class from accidentally damaging things. Dishonest use is possible, sure, just cast it down to the mutable form. But that's deliberate, and if you're own code is doing that, then something else is wrong. If someone else is deliberately trying to mess up your vector, then C++ offers you the same shakey safety, casting away constness is very easy.

Incidentally a lot of Swing classes take it to the extreme and return a copy of the object. Ugh.

Unlike the previous example, the Vector2f returned from getPosition() can't be cast into a mutable form, but thanks to scoping your outer class can modify it. This of course assumes that Vector2f isn't final or contains so many methods that overriding it this way is a pain in the @ss. It does however do what you want it to, namely prevent someone else from modify the object while giving your class the ability to, if in a somewhat convoluted way.

This of course assumes that Vector2f isn't final or contains so many methods that overriding it this way is a pain in the @ss. It does however do what you want it to, namely prevent someone else from modify the object while giving your class the ability to, if in a somewhat convoluted way.

Thats quite a neat trick, I'll probably use that at some point, but in this actual case there are a lot of methods and to have to do this everywhere needed would be a large amount of work for not enough gain :-/

Would be nice to get a proper 'const', but I guess most people think that returning a copy is an acceptable solution :-[

No, agreed! Multiple inheritance causes more problems than it's worth (although I can come up with persuasive reasons to have it). Operator overloading is another thing I'm glad to see the back of, after a fashion!

Unsigned really used to annoy me - I mean, what's an unsigned byte? That just doesn't make any sense! You get used to it after a while though.

Thats quite a neat trick, I'll probably use that at some point, but in this actual case there are a lot of methods and to have to do this everywhere needed would be a large amount of work for not enough gain :-/

Same result as previous solution, but all you have to do is reimplement your "set" methods.

You can also make the MyVector2f and the "secret" methods package local, in which case you'd only have to implement MyVector2f once per package that was going to use it.

I'm a stong believer in scoping classes to the scope of their use. If a class is only used within another class, I make it an inner class. If it's only used by other classes in a given package, I make it package local, etc, etc But that's another debate altogether.

Personally, I think the existance of the "Immutable" design pattern and the need for convoluted solutions like those detailed above, should be argument enough for adding const, but that's just me. I'm sure there are a host of reasons, technical and otherwise, for it's exclusion, but it certainly would be nice.

One of the biggest reasons for having const is passing arguments by const reference. Without pass by reference in Java, const loses a lot of use.

Deftly stepping around the whole 'Java passes everything by value' argument, how is the C++ code:void Class::SomeFunc(Vector2f* position);any different from Java:void someFunc(Vector2f position);? This is another area that i feel like const would be handy - I don't want to pass in the actual object because i don't want it changed, yet making a copy is a waste of time. A simple const modifier is exaxtly whats needed (could this be a compile time check, and thus be added to the language without too much fuss?). Instead of the nice simplevoid someFunc(const Vector2f position);I end up with the rather more ugly:void someFunc(float x, float y);

Quote

Even Orangy Tang's example is usually not done quite that way in C++, usually a const reference is returned.

Well really its not what i usually come across in C++ code, its usually something likevoid Class:GetPos(Vector2f* pos);which is nice because the caller can just create the object on the stack and let it quietly go out of scope without worrying about a GC sticking its neak in....

Edit: its not a simple compile time modification, you can't tell if a given method will modify the object or not until runtime.

Deftly stepping around the whole 'Java passes everything by value' argument, how is the C++ code:void Class::SomeFunc(Vector2f* position);any different from Java:void someFunc(Vector2f position);

Generally they're not that different. In both cases you're passing in a copy of the pointer/reference to the object. Since it's a new copy, you can't cause the original pointer/reference to refer to a new object.

But that's a C++ pointer, not reference.

with

void foo(SomeObject &bar);

you've passed in the actual object via reference. This method has free reign on this object, including causing it to be an entirely new object altogether. Sometimes you want that sometimes you don't.

void foo(const SomeObject &bar);

Same thing, but bar can't be altered in anyway. No expensive copying, you get the object to work with and it's safe. Everyone's happy.

This is essential when templates come into play

template <class T>void foo(const T &bar);

that T could be a lowly byte to a gigantic object. Since you don't know, you really don't want to copy it, const reference passing becomes crucial.

And of course, being C++, there's about a billion other combinations, const pointers, pointer references, pointers to pointers, on and on.

Quote

Well really its not what i usually come across in C++ code, its usually something likevoid Class:GetPos(Vector2f* pos);which is nice because the caller can just create the object on the stack and let it quietly go out of scope without worrying about a GC sticking its neak in....

Why though? just do

const Vector2f &getPos() const;

no object creation takes place at all, and everyone gets a loot at the object in a safe way.

I think you're missing my point somewhat - I'm perfectly happy with the myrad of options that C++ presents, but rather miffed that providing similar safety in Java involves a large amount of tedious leg work

I don't see what dynamically loading the classes has to do with compile time const checking. For one most C++ implementations have support for dynamically loaded classes/libraries, it's just not universal like Java's is.

I'd imagine it's a matter of adding an additional flag to the symbol table, and checking the flag at each assignment operation. Or there's probably a better way as that'd likely be expensive.

But if all classes come from the same compiler, then I don't see how the fact that they're dynamically loaded matters.

C++'s const checking is far from perfect. Like I said earlier, you can explicitally cast away constness (something the compiler's aware of and is ok with) or it's also possible to sneak constness off in ways the compiler doesn't realize. In the end the developer still has to have a head on his shoulders All these things like const are just there to help, not be absolute.

Well, as an example: I'm using an imaginary lib that has Vector2f, which has a .angleTo(Vector2f) call. Now in a function i'm using what is supposed to be a const vector, and since the angle function returns the angle and leaves the vector alone all is good.

But then on another system the program is run, and the same lib is using a different version which (for reasons unknown) normalises the vectors while calculating the angle - the const object has been changed and theres no way for the compiler to pick up on it.

The interface to his method needs to declare that. He either accepts a const vector or a nonconst vector, and that generally indicates if the object could or won't change. If his interface declares a nonconst argument, it's an error to send a const argument to that method, either runtime or compile depending on when it could be caught.

It's sort of like using say java.awt.Color.RED in Java 1.3. That field doesn't exist, it's a compile time error. But if you took a 1.4 class that uses Color.RED in a 1.3 JVM, it becomes a runtime error and the jvm properly catches it. It'd (I assume) do the same for const.

But again, const is just the language/compiler trying to help out, it's not absolute. If you're working with some unknown library that accepts a const vector, for all you know he had to write in some kind of kludge in that method which removes the constness and changes your vector. Maybe he did that to fit his own needs and didn't consider other users. That's really terrible programming, but it happens.

But then on another system the program is run, and the same lib is using a different version which (for reasons unknown) normalises the vectors while calculating the angle - the const object has been changed and theres no way for the compiler to pick up on it.

Couldn't you make the const-ness of the arguments and return types an integral part of the method signature? Also, allow subclasses to offer the same or a more strict version of method args, and the same or less strict return values?

Hrm, actually I'm not sure that would be so useful. Needs some thought...

Quote

Yes, but then again... so it goto...

Yeah, can't *wait* for that to be added!

Quote

1

StringwhatAbout = "String " + "concanenation?";

That's very well known, a specific case, and any confusion created is *totally* outweighed by its usefulness. I disagree with user-generated operator overloading because people start creating things like:

Q: Is there any plan to support the const keyword in the future, as in C++? If not, is there a reason?

Josh Bloch: We do not have plans to add support for the const keyword to the Java language. It was a mixed blessing in C++; as you know, it's merely advisory, and can cast on or off. Gosling hated it, and did final instead. What you really want is "immutable," but it's a research problem to make this work properly.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org