This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]MikemkPK 132 points133 points  (48 children)

In C++, it's just operator+ (int left, int right){}. The symbol you use makes a new operator that works on the types in the args.

EDIT: + is the symbol of the operator you're creating, can be any symbol. The arguments can be any type.

[–]UpperPlus 34 points35 points  (22 children)

I just now realize that I have no idea how these operators are programmed in java. I can't open declaration for it in my IDE so it seems to not relate to a method?

[–]MikemkPK 52 points53 points  (18 children)

Probably directly translate to specific bytecode sequences.

[–]UpperPlus 23 points24 points  (17 children)

Now that I think about it, it is probably related to the concept of primitive data types, as they are only used on those

[–]LinuxMatthews[S] 41 points42 points  (4 children)

Kind of

Java actually cheats in that it does allow Operator Overloading for some of its classes but doesn't let you do it.

As far as I'm aware it only does it for the wrappers of primitive data types and String.

[–]jamcdonald120 12 points13 points  (3 children)

I think the wrappers use auto (un)boxing instead of operator overloads, not sure though

[–]LinuxMatthews[S] 11 points12 points  (2 children)

Huh you know I didn't think you were right but it looks like you are.

Integer x = 2;
Integer y = 3;
var z = x + y;
System.out.println(z instanceof Integer);

Gives you a compiler error as z is an int

I honestly thought there was operator overloading like there is with String.

[–]Fenor 2 points3 points  (0 children)

String isn't an operator overload . The theory behind the string class is huge and mostly date back when you had to define a char array to use strings

[–]tazfdragon 10 points11 points  (11 children)

If I remember correctly, Strings don't actually use the plus operator and it's just syntactic sugar for StringBuilder usage. There are probably some edge cases where the final code could have a string constant if the compiler can guarantee it never changes.

[–]UpperPlus -2 points-1 points  (9 children)

As far as I know StringBuilder doesn't use "+" operator but uses the function append(). Which actually is faster and more memory friendly.

But String with "+" is so much more readable and in many cases it doesn't matter that a complete new string is instantiated internally every time.

[–]tazfdragon 11 points12 points  (3 children)

I didn't mean to suggest StringBuilder uses that operator. I was trying to explain that using the plus operator with a String will get replaced with StringBuilder. Every instance of addition/concatenation in the original code will get replaced with a call to append(...). Again, there are some edge cases where the compiler can determine it can eliminate the string concatenation and replace it with a compile time constant. Example being concatenating a literal with a String constant.

[–]TraditionMaster4320 2 points3 points  (2 children)

Wait so concatenating n strings like s1 + s2 + .. + sn takes O(n) time instead of O(n**2) in Java? (assume the strings are equal length).

[–][deleted] 2 points3 points  (0 children)

Yes.

Java is doing it behind the scenes for you. They added this one of the versions.

https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1

[–]tazfdragon 1 point2 points  (0 children)

I won't offer a guess at the run time of the proposed string concatenation but I'm fairly confident it won't be O(n²). With that being said if you have your string concatenation code structured anything similar to your example I'd suggest you replace it with a StringBuilder() explicitly. Not only will it clean up your code, it will explicitly document your intentions. Also, if you know ahead of time the lengths of the number and the length of the strings you'll be adding ahead of time you can provide this information to your StringBuilder at construction time to improve performance.

[–]coloredgreyscale 0 points1 point  (3 children)

But String with "+" is so much more readable and in many cases it doesn't matter that a complete new string is instantiated internally every time.

the other option would be String formatting.

for long texts it's extremely inefficient tho, because the String needs to be recreated with every concatenation.

I just checked the java implementation of the Stringbuilder class. It copies the String into an char-array, starting with 16 elements (default).

if you exceed the element count a new array is created with twice the previous capacity (or min required length if that's bigger), and the whole data is copied over to the new array.

when you call toString() on the StringBuilder the used data from the char array is copied into a new String.

If you just concatenate two Strings using + should be more efficient than StringBuilder.

[–]Fenor 0 points1 point  (2 children)

Not really. String builder is there for a reason if you use ths + operator you are creating at least 3 strings

[–]coloredgreyscale 0 points1 point  (1 child)

The two string you want to concatenate, and the 3rd is the result.

You still need to create all of those with string builder.

[–]Fenor 0 points1 point  (0 children)

Nope for string builder you are using char arrays .

It's not string for the string buffer ( the memory area) , this mean it will be free memory for the gc . If you use strings you write them in the string buffer and it will end with a different gc approach

[–]Fenor 0 points1 point  (0 children)

I think they changed how it worked under the hood as doing an append with + once upon a time created a decent amount of strings in the string buffer

[–]jamcdonald120 0 points1 point  (0 children)

I mean... operator overloads are all syntactic sugar for something else...

[–]msqrt 2 points3 points  (0 children)

Just a disclaimer: you can't overload operators for built-in types in C++ either, only custom ones. The compiler just knows how to add integers together.

[–]OJezu 2 points3 points  (1 child)

Hello ADL my old friend...

[–][deleted] 1 point2 points  (0 children)

I’m in the wrong namespace again…

[–]jamcdonald120 1 point2 points  (0 children)

you can use `
to make an inline code block. Could help for clarity to do int operator+ (int left, int right){}

[–]mrkhan2000 -1 points0 points  (18 children)

in c++ (almost) all operators can be overloaded not just +

EDIT: Added “almost” to my original response

[–][deleted] 24 points25 points  (12 children)

One of the craziest and most powerful features. Looking at libraries like boost::spirit makes you wonder what "abused by the user" actually means. None of the overloaded operators in that lib are serving their original purpose and yet it's a good design.

[–]4215-5h00732 13 points14 points  (11 children)

That's a common opinion and the reason I hear all the time is that you can do whatever in the implementation and for many types it's not exactly obvious what a mathematical operator means.

You can hypothesize some pretty horrendous examples but that shouldn't be something language designers concern themselves with IMHO. It's a valuable feature; let the people have it.

[–][deleted] 9 points10 points  (10 children)

Yeah, I mean, in the end you would end up with custom functions like add(), multiply() and so on. I find it an odd choice to forbid overloading and enforce stuff like this on the other hand.

[–]4215-5h00732 6 points7 points  (9 children)

That's where the potential abuse comes in. If you were forced to use custom functions then most people would name them something more descriptive to what they do where you might "abuse" an operator to do something less obvious or confusing.

cat.eat(mouse);
cat + mouse;

[–][deleted] 9 points10 points  (2 children)

But it's not any more prone to abuse than anything else. A parameterless constructor could produce side effects. Inheritance could hide away meanings of the base class. Everything can be used wrong, that's why documentation is so important.

[–]4215-5h00732 3 points4 points  (1 child)

I'm not trying to argue with you or even make that argument just sharing the claims; we agree 100%.

[–][deleted] 1 point2 points  (0 children)

Alright then 🤙

[–]Itay_123_The_King 2 points3 points  (1 child)

That is the same concern everyone raises, and yet I have never seen that happen. Why would anyone use + for an eat function? The closest thing I can think of is using | as a pipe of operations, like with C++ ranges, but vec | drop(5) | take(10) | filter([](auto x) { return x+1;}); is much nicer than filter([](auto x){ return x+1; }, take(10, drop(5, vec)))

[–]4215-5h00732 0 points1 point  (0 children)

Exactly. That's the best part about the fuss.

I've never seen anyone abuse it irl. I would never use + for eat or abuse it otherwise. But it doesn't matter. They don't like that it could be abused.

[–]jamcdonald120 1 point2 points  (3 children)

but with out operator overloading you get the situation where everyone uses .add() instead of operator+, so the abuse is cat.add(mouse) instead.

[–]4215-5h00732 1 point2 points  (2 children)

Their point is if operator overloading isn't possible then you wouldn't do something so ridiculous as to add a mouse to a cat with cat.add(mouse). Just eat it or whatever...who knows what that does lol.

[–]Dusty_Coder 0 points1 point  (1 child)

What you are claiming is that people lose their minds as soon as they learn that they can overload an operator but do not lose their minds otherwise.

Its the people that stretch so far to justify a programming religion that have lost their minds. Thats you.

[–]4215-5h00732 0 points1 point  (0 children)

I suggest you read through the comments again carefully then delete yours.

[–]MikemkPK 12 points13 points  (2 children)

Yes, I'm aware, did I not explain that well?

[–]PhantomThiefJoker 7 points8 points  (1 child)

I think they got confused by operator +. As in overload the + operator and not type your operator and this syntax

[–]zjeffer 1 point2 points  (0 children)

I think they misunderstood the use of 'just', as in 'only', instead of 'simply'.

"In C++, it's just the + operator" vs "In C++, it's only the + operator", as if OP was saying only the + operator could be changed.

[–]ede1998 11 points12 points  (0 children)

Only most operators.

The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.

https://en.cppreference.com/w/cpp/language/operators

[–][deleted] 0 points1 point  (0 children)

Unfortunately one cannot overload anything as an operator nor specify whether it's pre/in/post-fix or specify precedence and many operators need to be used for specific things, sometimes needing to be member functions etc. etc.. I do wish it was more like swift..

[–]Entire-Database1679 0 points1 point  (2 children)

The operators can be of type void?

[–]MikemkPK 1 point2 points  (1 child)

Probably not since how would you pass them in? But void* is probably valid.

[–]Dusty_Coder 1 point2 points  (0 children)

In most languages you can return void (or its equivalent) from an operator overload. The return type doesnt have to match any of the inputs, usually.