#is everything in Java a pointer ?

1 messages · Page 1 of 1 (latest)

lime knoll
#

I was learning C++ and having incredibly hard time deciding if I should use pointer or pass value... I was trying to relate it to java but it only has 1 kind of variable so are they all just pointers

wide quartzBOT
#

<@&987246683568103514> please have a look, thanks.

#

Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#
TJ-Bot
I was learning C++ and having incredibly hard time deciding if I should use pointer or pass value... I was trying to relate it to java but it only has 1 kind of variable so are they all just pointers

In Java, everything is passed by value, not by reference. The confusion may arise because objects in Java are actually references to memory locations. So when you pass an object to a method, you are passing the reference (or pointer) to the object, not the object itself.

Useful links:

  1. Java is Pass-by-Value, Dammit!
  2. Is Java "pass-by-reference" or "pass-by-value"?
  3. Understanding Java Pass by Value and pass by reference
lime knoll
#

ah are they all references

twilit heart
#

The relationship is similar. Java was marketed to C/C++ developers at the time. 32bit was convenient for holding primitives or a pointer. They are both convenient to pass by value.

lime knoll
#

It is kinda confusing between references and pointers too

#

I feel effectively they both do the same thing

#

Pass by value seems expensive because it copies entire object

twilit heart
#

handle, reference, pointer to, I use them interchangeably.

#

It doesn't copy an object, it copies the handle/reference/pointer to the object.

summer cargo
#

well 'pointers'

#

all objects are pass by reference, everything else isnt iirc

lime knoll
#

I am trying to relate C++ to Java to smooth en my learning experience

#

not sure if its okay tho

high hornet
lime knoll
#

are primitives references too?

high hornet
#

When the ref is not kept by any variable the object is gc

#

Yes, to the memory where they are allocated,

lime knoll
#

alright ty

cursive orbit
#

And another thing to point out is that these objects are created on the heap right?

#

As opposed to the stack?

dusk copper
#

thats not specified

#

any JVM can do whatever it wants in that regard

#

JVMs like hotspot have a virtual memory layer and then move stuff around constantly to improve it based on runtime info

dusk copper
#

u should generally stay away from raw pointer (unless u have to) and instead use the smart pointers

#

what ull pass depends on what u want to achieve

#

in general, u have to think about ownership topics. which u dont need to do in java

#

here is a quick overview:

cursive orbit
#

So are allocations in Java kinda like Rc<Type> in Rust?

#

Or Arc<Type>

dusk copper
#
void foo(Person person) { ... } // pass-by-value, the method gets a clone and owns that clone, it is its own person object

void foo(Person& person) { ... } // pass-by-reference, the method gets a ref to an existing person. it wants to work with the person, maybe manipulate it. the caller must ensure person is alive while foo runs bc the method will not own the object or extend its lifetime

void foo(Person* person) {...} // pass-by-pointer, object on the heap. avoid this. intention is too unclear (especially ownership)

void foo(std::shared_ptr<Person> person) { ... } // pass-shared-by-value, an object on the heap, the method has shared ownership. the method and the caller own the object

void foo(std::weak_ptr<Person> person) { ... } // pass-weak-by-value, the method wants to be able to claim ownership on the person, but at a later point in time, not now. currently the method does not hold ownership

void foo(std::unique_ptr<Person> person) { ... } // pass-unique-by-value, an object on the heap. ownership is transferred from the caller to the method. the method now owns the object, the caller cant use it anymore
#

this is usually whats available to u in C++

#

as u see, all of them deal with the topic of ownership and object lifetime

#

thats what differentiates it from java

#

in java everything is essentially void foo(std::shared_ptr<Person> person)

#

and ownership/lifetime is managed automatically

#

in c++ its up to u to decide

cursive orbit
dusk copper
#

its way too complex to be able to straight out say whats better

cursive orbit
#

Yeah, fair enough

cursive orbit
#

Is * just a deprecated version of &?

dusk copper
#

no

#

& is a ref to an object, explicitly expresses that the lifetime is not claimed/managed and that the caller needs to take care of keeping the object alive

#

it also cant be reassigned

#

unlike a pointer

#

a pointer doesnt clarify ownership questions

north crown
#

There is some debate as to whether they're called pointers or references (because they're not actual pointers, they can be multiplied and/or offset), but as long as it's not a primitive, yes it's a pointer/reference

dusk copper
#

"do u just want to work with it but i hold ownership? do u want to have shared ownership? do i transfer ownership to u and ur managing the object now?"

#

a raw pointer doesnt clarify these points

cursive orbit
dusk copper
#

if u will, i guess

#

but ur discussing the technical side of it

#

im talking about how its used

#

and how people will understand it

north crown
#

yes, because Java is pass by value

#

So you can't change the argument passed into the function, only what it possibly "points" to

dusk copper
#

if u write foo(Person& p) everyone knows that the method will not claim ownership

north crown
#

Changing items in an array or collection for example

dusk copper
#

if u write foo(Person* p) thats totally unclear

north crown
dusk copper
#

even worse when u return a pointer out of a method

#

Person* givePerson()

#

who owns the person? do u just get a view on the object or is the person now transffered and u have to manage it?

north crown
#

My biggest gripe with C/C++

#

That's why I just use Rust when I need some low level shenanigans 😄

#

I don't have time to think about all that lol

dusk copper
#

in proper modern c++ u wont see raw pointers being used much.
occasionally u run into them though when people think their C api is a proper C++ api as well

#

and hence only offer one C/C++ api

north crown
#

yeah, it's never your own program that's the issue

lime knoll
#

btw sorry if I take time to reply, I am still trying to process it.. It just doesn't sit right with my brain for some reason

north crown
#

The trick is to not think about it too much

lime knoll
#

See problem is when I try to write some basic code I get lost into thinking what kind of variable should I use

north crown
#

Ah, so, and I'm going to hammer this in now

#

Use the correct one

lime knoll
#

from what I have been thinking is that pointers are not to useful but references are way to go

north crown
#

Read up on some domain driven design, and write some little value types

#

An email should not be represented as a string

#

But as an Email

dusk copper
north crown
#

A birthday isn't a string, it's a LocalDate

#

An UserId isn't a long, it's a UserId

#

"I have some unique items", that's not a List, that's a Set

#

etc

lime knoll
dusk copper
#

object lifetime

#

who takes care of killing the object or keeping it alive

#

thats ownership

lime knoll
#

oh

dusk copper
#

in java things are alive as long as someone uses them (shared pointer in c++)

#

in c++ u have full control over that

#

u decide when an object is destroyed. so u also have all these new use cases of "here is my object. but u dont own it" and "here is my object. we both own it now" and "here is my object, from now on its urs, i dont own it anymore"

#

and thats why u have so many pass-by variations

#

to decide on exactly that

#

who owns the object (lifetime-wise)

lime knoll
#

who has the ownership in case of normal pointers? (Person*)

dusk copper
#

its unclear. thats why u should avoid it

#

raw pointers arent auto-managed. they have to be destroyed manually

#

so its unclear who will do that

#

delete pointer

lime knoll
#

can u gc variables urself in C++?

dusk copper
#

there are GC extensions for c++, but its uncommon

lime knoll
#

I see

dusk copper
#

the closest to java that ull get with normal c++ is using std::shared_ptr everywhere

#

(and passing those around by value, so everyone claims shared ownership while using the object)

lime knoll
#

I can see some use cases of almost every type of variable apart from normal ptr

dusk copper
#

the smart pointers are there to replace the raw pointer

#

the underlying thing is a raw pointer still

lime knoll
#

I see

dusk copper
#

but its wrapped with a smart pointer to clarify intention

lime knoll
#

I guess they exist so u don't have to use raw pointers

dusk copper
#

exactly

lime knoll
#

is there any difference in shared pointer and reference?

dusk copper
#

a reference doesnt keep the object alive

#

and it cant be reassigned

lime knoll
#

oh so its final and not null

dusk copper
#

a shared ptr claims shared ownership

#

a ref not

#

someone can kill an object while u have a ref to it

#

then its dead

#

and u run into undefined behavior

#

with a shared ptr that wont happen

lime knoll
#

does it just crash the program or throw an error

dusk copper
#

undefined behavior

#

anything can happen

#

if ur lucky ull get a crash with an error

#

if ur unlucky it might still have the object there and work. so u deploy and 2 weeks later it crashes on PROD

#

or it might read the data of another object that took the place in memory already and do something weird without crashing

#

classic undefined behavior

#

this is also why its generally dangerous to give references out of a method

#
Foo& foo = getFoo();
...
foo.doSomething(); // is foo still alive or did someone kill it in the meantime...?
lime knoll
#

Yeah that is pretty dangerous

#

can u check if it is alive?

dusk copper
#

no

#

ull see it mostly being used as shortlived method parameters

#

for example

lime knoll
#

maybe helper methods?

dusk copper
#
...
feedHuman(john);
...
lime knoll
#

Yeah

dusk copper
#
void feedHuman(Person& person) {
  person.eatSomething(banana);
}
lime knoll
#

do u have to type std:shared_ptr<Foo> foo for every param? I feel thats kinda big and reduces readability

dusk copper
#

this is generally safe as the caller of the method knows that they need to keep john alive while the method runs

dusk copper
#

otherwise not

lime knoll
#

ooof

dusk copper
#

it all boils down to what u want to achieve. and yeah, the difference really is that in c++ ur constantly confronted with the question "who owns that object?"

#

and based on that u make ur decisions

#

for example the name of a Person belongs to the person. its theirs

#
class Person {
  std::string name;
  ...
};
#

so a getter would either return a copy or potentially a reference (but thats dangerous)

#

but definitely not shared ownership, weak ptr. and unique ptr wouldnt make sense at all

lime knoll
#

it makes sense to return reference tho right?

dusk copper
#

yes and no

lime knoll
#

the variable name shouldn't get gc-ed as long as Person object exists

dusk copper
#

the class cant ensure that name is still alive

#

so its potentially dangerous

lime knoll
#

oh

dusk copper
#

see, the thing is the following:

#
Person* p = new Person("John");
...
std::string& name = p.getName();
...
delete p;
...
std::cout << name; // UB
#

person is dead. so is the name. but the std::string& name is still there. running into undefined behavior

lime knoll
#

oh that does make sense

dusk copper
#

thats why im saying its potentially dangerous

#

the Person class itself cant ensure that the name is still alive when the caller uses it

#

id still say that returning a reference is okay here, bc the caller will know that its bound to the person object

#

but in some more complex scenarios this can be a problem

lime knoll
#

While reading the book, it said that stuff like primitives are okay to be passed as value while classes etc shouldn't be passed as value because they are expensive to copy

dusk copper
#

for example when the Person gives out a reference to an object it doesnt own itself

#

lets say for example:

#
class Person {
  std::weak_ptr<Person> bestFriend;
  ...
  Person& getBestFriend() { ... }
};

this is really dangerous

#
Person john = ...
...
Person& bestFriend = john.getBestFriend();
...
#

the caller assumes that the bestFriend is bound to johns lifetime

#

but its not

#

its bound to janes lifetime (or whoever is the best friend)

#

and thats not managed by john

#

so yeah. u can run into dangerous setups

#

if ur not being careful

#

in case of a name its okay to return a copy

#

but if the object is big in terms of size. or this is called really often, a reference can be reasonable

#

if u return a reference, the caller can still make themselves a copy right away if they want to have hands on the object beyond the lifetime

lime knoll
#

I feel everything but shared ptr is scary

dusk copper
#
std::string& name = p.getName();
std::string myOwnName = name;
#

u can do sth like that and then its urs

#

or directly put it into a value object:

#
std::string myOwnName = p.getName();
#

so if u return a reference, the caller can kinda decide for themselves if they are okay with a ref or if they need their own clone

dusk copper
#

if latter, u can use the smart pointers

#

like, std::unique_ptr is kinda the equivalent to a normal value

#

std::string name and std::unique_ptr<std::string> name are essentially the same

#

with the difference that one is on the stack and the other is the heap-variant

#

it means "this is my object. not urs, its mine"

#

in both cases, the object can be transffered though (using std::move)

#

"its urs now. i dont need it anymore"

lime knoll
#

can u just move stuff?

dusk copper
#

yes. moving means transferring

lime knoll
#

this does not feel very safe

dusk copper
#

important to keep in mind is that ur old variable must not be used after a move anymore

#
std::string first = "hello";
std::string second = std::move(first);
std::cout << first; // UB
#

cause the old variable is "dead" now

lime knoll
#

I am feeling like I must be very careful with the access I provide to different classes and methods

#

If they can delete/move anything when ever they want

dusk copper
#

c++ just gives u all options and full control when it comes to lifetime/ownership questions

#

u only need to get comfortable with them

lime knoll
#

I assume it till take time

dusk copper
#

the thing is just that in c++ its generally easier to make a mistake without noticing

#

less safety wheels

lime knoll
#

oh yeah reflection is ew

#

In 2yrs of writing Java code I have never found a reasonable use case of reflection

#

I assume u have been writing for over a decade did u find any reasonable use case of reflection?

dusk copper
#

its mostly with meta programming. not when u do normal software

#

think about tools like Jackson

#

(json to java pojos and back)

#

or tools like debuggers

#

IDE plugins

#

that kind of stuff

#

code that needs to deal with other code on a meta level

#

or annotation heavy frameworks like Spring

#

hibernate

lime knoll
#

I see

#

Well ty for the help btw I appreciate it, I will write some simple programs like calculator to try to learn stuff practically

#

I am not going to lie I didn't know that smart ptrs existed

cursive orbit
dusk copper
#

there is a book called Effective Modern C++ which i generally can recommend. but its not good for beginners and very technical

#

most c++ content is very focused on technical topics rather than how to write software effectively

#

there is also A Tour of C++ by the author of c++. but this is a very technical book

#

good for exposure to features though

#

there are a few pitfalls in c++ that one needs to be aware of and these books can help with that

#

inheritance/overloading/virtual for example are easy to make mistakes with

#

and ofc the whole lifetime topic

#

accidentally accessing sth after it was deleted is probably one of the most common bugs in real c++ code

#

or accessing data that was never initialized (although modern IDEs like VS or CLion are usually fairly good detecting that)

#

example

class Foo {
  Foo() {}

  bool flag;
};

Foo foo;
std::cout << foo.flag;
#

in java the flag is guaranteed to be initialized to false. in c++ its undefined behavior

#

could be false, could be true, could also crash the program, ...

#

(there are some cases where it will be initialized, for example through the default constructor. and cases where it wont)

#

or C-style arrays:

string lines[10];
std::cout << lines[0];
#

unlike java, not initialized with default values like "". but instead UB

#

cause "why pay the performance impact of explicit default values if we maybe dont even need it?"

#

thats kinda the theme with c++

#

dont pay for sth that u havent asked for

lime knoll
#

I mean I know basics but I am trying to learn it properly

#

The best thing I liked in C++ is u can also do stuff when class destructs

dusk copper
#

its rarely useful in "normal classes" but gives birth to a lot of cool ideas generally called RAII

#

the smart pointers for example make use of it

#

or something like a lock/mutex

lime knoll
#

I made a simple Defer class using it

dusk copper
#

or u can for example do stuff like

lime knoll
#

💀 what will happen if u try to delete the object while it is trying to destruct

dusk copper
#
{
  measureThis m;
  ... // do something
} // measureThis could now end measurement and print statistics or sth
...
#

so u dont have to explicitly call sth like a start/stop method

#

using object deletion in that way is cool. (but could also catch people offguard if overused)

#

but yeah. thats how smart pointers work

#

(as they are just ordinary c++ classes technically. and not a "language feature")

lime knoll
#

I think it is cool because u could call some clean up methods too

dusk copper
#

yeah

lime knoll
#

or maybe events

dusk copper
#

resource cleanup is a good argument

#

sth that is more difficult in java (well, we have try-with-resources, but still)

#

the more modern file api in c++ also makes use of automatic resource handling through RAII

lime knoll
#

yea it is not as neat in Java

#

It is just java produces some of the most readable and maintainable code

#

Java isn't very complicated either

dusk copper
#

in general i think its great to have a look at other languages, learning all the pros and cons of things they did. very interesting experience as well

lime knoll
#

Yeah, I think every language has something u can really appreciate or something u can really hate

#

While using GoLang I appreciated the defer and the fact u could add string identifiers to variables but it's generics suck

cursive orbit
dusk copper
#

its a 2 sided coin

#

more control means more responsibility

#

and more ways to mess up

#

but it also means, well, more control

lime knoll
#

With great power comes great responsibility

cursive orbit
dusk copper
#

when u demand pass-by-value, u get copy by value

#

Person is a value object

#

Person& is a reference

#

Person* a pointer

#

when u demand Person, u get a Person

#

meaning ur own instance

cursive orbit
dusk copper
#

so unless ur getting moved-to or similar, ull get a copy

lime knoll
cursive orbit
dusk copper
lime knoll
#

I'd recommend u to take a look at those languages yourself

cursive orbit
#

Since it's a functional programing language right

#

Pure one

dusk copper
#

those arent really used on normal software dev at all

#

only for very special use cases

lime knoll
#

Yeah it is a purely functional lang

cursive orbit
#

I think a bit?

#

Right?

dusk copper
#

give it a try and ull quickly see why its not meaningful

lime knoll
#

I think even comparing Java and C is not fair

cursive orbit
#

I heard it's type system is some of the strongest

dusk copper
#

its just a totally different thing meant for something totally different

lime knoll
dusk copper
#

if u try to do normal software dev with it, u wont really like it

#

or not come far with it

#

it shines in other areas

cursive orbit
dusk copper
#

its more that the paradigm of doing pure functional programming doesnt work well with large software at all

#

its less about haskell specifically

lime knoll
#

honestly I feel people would be more than okay to use Java for Game dev rather than C++ if there was enough eco system for it

#

I think it mostly depends on the eco system for languages

#

Languages like Rust and go are still developing their eco systems

zenith basin
dusk copper
zenith basin
#

because its related to references ?

dusk copper
#

mh. fair. it was kinda on a different topic though

#

but yeah, objects and references exist in java as well. it has a different meaning to c++ though

cursive orbit
#

It was going well till I kept checking the comments on the answers and they kept going into wars of saying "no, that's not correct" or something like that 💀

#

And now I'm on the fence as to which answer there I'm supposed to be reading..

#

They're all contradicting each other rip

#

Each with their own new set of definitions

north crown
#

Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before

#

From oracle

#

I follow that definition for Java lol

cursive orbit
#

The peeps there in that post

north crown
#

🤷

marble onyx
#

So, just to confirm: primitives are passed as value and objects as reference, right?

high hornet
small halo
high hornet
spark quartz
#

But the variables only store references

#

So it ends up being the same reference

small halo
#

it's just that the value is the reference

marble onyx
#

I knew that objects by default were passed by reference, and that you need to clone them if you don’t want that to happen (to put it simply), but I was confused by the terminology

small halo
#

pass by reference means that you create a reference

#

so if you have a raw value, pass by reference means you create a reference to the value

#

if you have a reference, pass by reference means you create a reference to the reference

#

pass by value means you pass the value itself, regardless of what it is

twilit heart
marble onyx
north crown
#

There's a reason I posted the docs

#

RTFM

cursive orbit
#

Most use JDK 17+ right

north crown
#

still counts

#

that's so core to java, that hasn't changed in forever

cursive orbit
#

Fair

marble onyx
zenith basin
#

a few patterns use making constructor private to give away their own implementations that are available