In Java, when you assign one object to another, the original object isn't copied, it merely clones the reference. So, for example, I'd like it to behave like this Java code:
SomeClass x = new SomeClass();
SomeClass y;
y = x; // x is not copied, y is simply a (Java) reference to x
What I'd like to do is create a C++ class that behaves the same way. The obvious choice is to overload the assignment operator, like so:
SomeClass& operator=(const SomeClass& rhs)
{
this = &rhs;
return *this;
}
Unfortunately, assigning a new location to this is not allowed; the above code won't even compile.
Does anyone know of any other way to do this?
Also, before you say anything: yes, I know this is absolutely the wrong way to implement an assignment operator. Please, indulge me anyway.
EDIT 2: To clarify, here is the C++ code that should behave as in Java:
SomeClass x = SomeClass(); // Created on stack
SomeClass y; // In C++, same as above; NOT reference or pointer
y = x; // x is not copied, y becomes a (C++) reference to x;
// original y is destroyed when stack unwinds
I DO NOT want to use pointers at all.
EDIT: I'm doing this to see if I can change the base address of a C++ object that was passed by reference to a function. If I simply assign another object to the reference variable, it automatically makes a shallow copy, and I don't want that. I want the reference parameter to reference a completely different object.
I'm doing this to see how references are implemented by the compiler. If references are syntactic sugar for dereferenced pointers, then outside the function, the base address of the argument object would NOT change. If they are aliases in the symbol table (as in PHP), then it WILL change. (So any solution using pointers is out, since that's my "control" for the test.)
Hope that makes sense.
This isn't possible. The languages just work fundamentally differently.
SomeClass x in Java is some kind of pointer or reference to a SomeClass object. It's an indirection, so that why you can have multiple ones refering to the same object.
SomeClass x in C++ literally is the object. Thus SomeClass y is literally an entirely different object. There's no indirection. And so there's no way to make one reference the other.
C++ provides pointers (SomeClass* x) and references (SomeClass& x) to take care of the times when indirection is needed. Perhaps those are what you actually want to use, although it depends on why you asked this question in the first place.
Responding to the edit:
No, you can't change the address of an object. An instance of an object will live in exactly one place for the duration of its lifetime, until it is destroyed/deallocated.
I don't think this is okay, because even you assign this to another pointer, then the current object pointed by this will be memory leaked. Java has memory collection, but C++ not.
This is a good question, through. And this is possible.
A& operator=(const A& rhs)
{
A * cthis = const_cast<A*>(this);
cthis = const_cast<A*>(&rhs);
return *cthis;
}
Edit: It is possible to change "this pointer" inside a member function. But changing "this pointer" doesn't accomplish much.
It can be done. but, with pointer indirection.
Lets say you have a class someClass
class someClass
{
someClass *someClsPtr;
public:
someClass(someClass *someClsPtrTemp):someClsPtr(someClsPtrTemp)
{
}
someClass* operator=(someClass *someClsPtrTemp)
{
this->someClsPtr = someClsPtrTemp->someClsPtr;
return this;
}
//now over load operator -> and operator *. Thats it.
};
Related
Imagine I have a Base class, and two classes that derive from it, One and Two. In Java, I could have the following scenario:
Base b;
if(condition)
b = new One();
else
b = new Two();
where the object type is determined at runtime (the above objects go on the heap).
In C++, I want to be able to instantiate the object type at runtime as well - where all I know is that they both share the same Base type - but I want to keep it stack allocated, like so:
Base b;
What's the best way to do this?
What's the best way to do this?
You can't. If you declare a variable type as Base, the stack allocation for it will be suitable for holding an instance of Base but not an instance of a derived type (which might be larger, though even if it is not, you still cannot do what you ask; the runtime type of a variable in C++ is always the same as its declared type). At best, you could slice the derived instance into a Base-type variable.
The best bet is to use a pointer, optionally wrapped in a shared_ptr or unique_ptr to give you similar semantics (i.e. to have the object be automatically destroyed when it goes out of scope, assuming ownership hasn't been transferred).
Base* b = (condition) ? (Base *) new One() : new Two();
auto bptr = shared_ptr<Base>(b);
Note that what this gives you is effectively the same as the Java. The object itself is heap allocated, but the reference to it is stack allocated. Despite the syntax, a reference-type Java variable is essentially equivalent to a pointer in C++.
Take, for instance:
Derived d;
Base* b = &d;
d is on the stack (automatic memory), but polymorphism will still work on b.
If you don't have a base class pointer or reference to a derived class, polymorphism doesn't work because you no longer have a derived class. Take
Base c = Derived();
The c object isn't a Derived, but a Base, because of slicing. So, technically, polymorphism still works, it's just that you no longer have a Derived object to talk about.
Now take
Base* c = new Derived();
c just points to some place in memory, and you don't really care whether that's actually a Base or a Derived, but the call to a virtual method will be resolved dynamically.
So, it seems, unlike Java, there is no way to achieve dynamic binding without heap allocation or pointer way.
As comments said you cannot. Well, you could but that wouldn't run:
Base &b = *(condition ? (Base *)&One() : (Base *)&Two()); // BROKEN CODE DO NOT USE
(Builds using -fpermissive, but don't do this!)
since One & Two objects are temporary objects. b would be invalid as soon as you step through next line => don't do this (not sure I said it already)
The following works, but not perfect: build both objects on the stack, so OK only if you can afford it. Just choose according to condition:
One one;
Two two;
Base &b = *(condition ? (Base *)&one : (Base *)&two);
To avoid the double allocation, the closest thing I can think of in terms of usage would be to take a reference of allocated objects (still not auto variables, sorry):
Base &b = *(condition ? (Base *)new One() : (Base *)new Two());
So you can use b as Base in your code.
You still have to delete memory with
delete (&b);
In order to use inheritance in C++ you will need to define a pointer, not a static object, and then instantiate it with new keyword.
Example:
Base* b;
if(condition)
b = new One();
else
b = new Two();
I'm a complete Java noob. I know that Java treats all parameters as pass by value and there are several other threads where people explain this.
For example, in C++ I can do:
void makeAThree(int &n)
{
n = 3;
}
int main()
{
int myInt = 4;
makeAThree(myInt);
cout << myInt;
}
Which will output 3. I know that in Java, all parameters are passed by value and thus you can not manipulate the parameter passed in. Is there a standard way to simulate pass by reference in Java? Is there no way to call a function that manipulates a variable passed in? It's tough for me to wrap my head around the idea of there being no way to do this.
The primary way you can simulate passing a reference is to pass a container that holds the value.
static void makeAThree(Reference<Integer> ref)
{
ref.set(3);
}
public static void main(String[] args)
{
Reference<Integer> myInt = new Reference<>(4);
makeAThree(myInt);
System.out.println(myInt.get());
}
Since in Java, it is references to objects that are passed by value (the object itself is never passed at all), setting ref to 3 in makeAThree changes the same object referred to by myInt in main().
Disclaimer: Reference isn't a class you can just use with out-of-the-box Java. I'm using it here as a placeholder for any other object type. Here's a very simple implementation:
public class Reference<T> {
private T referent;
public Reference(T initialValue) {
referent = initialValue;
}
public void set(T newVal) {
referent = newVal;
}
public T get() {
return referent;
}
}
Edit
That's not to say it's great practice to modify the arguments to your method. Often this would be considered a side-effect. Usually it is best practice to limit the outputs of your method to the return value and this (if the method is an instance method). Modifying an argument is a very "C" way of designing a method and doesn't map well to object-oriented programming.
You can use an array of size 1
Java pass everything by value, if it's an object then what would be passed is the reference value of the object. It's like,
void someMethod()
{
int value = 4;
changeInt(value);
System.out.printlin(value);
}
public void changeInt(int x)
{
x = x + 1;
}
above code will print 4, because it's passed by value
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the object is passed by value and the reference to the object is passed here, even it's changed inside the method it won't reflect to the method 'someMethod'.
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls.x = cls.x + 1;
}
here also it passes the object by value, and this value will be the reference to the object. So when you change some field of this object it will reflect to the all the places where the object is referred. Hence it would print 5. So this can be the way you can use to do what you want. Encapsulate the value in an object and pass it to the method where you want to change it.
Java is pass-by-value that mean pass-by-copy. We cannot do arithmetic on a reference variable as in C++. In-short Java is not C/C++.
So as a workaround you can do this:
public static void main (String [] args) {
int myInt = 4;
myInt = makeAThree(myInt);
}
static int makeAThree(int n)
{
return n = 3;
}
P.S. Just made the method static so as to use it without class object. No other intention. ;)
I ran some of the various scenarios above.
Yes, if you wanted to change a value outside of the function without returning the same primitive, you'd have to pass it a single unit array of that primitive. HOWEVER, in Java, Array's are all internal objects. You please note that if you pass 'value' by name to the println() there is no compile error and it prints hashes because of the toString() native to the internal array class. You will note that those names change as they print (put it in a long loop and watch). Sadly, Java hasn't gotten the idea that we WOULD like a protected yet physically static address space available to us for certain reasons. It would hurt Java's security mechanisms though. The fact that we can't depend on known addresses means that it's harder to hack at that. Java performance is fantastic because we have fast processors. If you need faster or smaller, that's for other languages. I remember this from way back when in 1999 reading an article in Dobbs just about this argument. Since it's a web aware language meant to function online, this was a big design concession to security. Your PC in 1999 had 64mb to 256mb of RAM and ran around 800mhz
Today, your mobile device has 2 to 8 times that ram and is 200-700mhz faster and does WAY more ops per tick, and Java is the preferred language for Android, the dominant OS by unit sales (iOS still rocks, i gotta learn Objective C someday i guess, hate the syntax i've seen though).
If you passed int[] instead of int to this code you get 5 back from someMethod() calling it.
public void changeInt(int x)
{
x = x + 1;
}
public void changeInt(int[] x)
{
x[0] += 1;
}
This is a confusing selection from above. The code WOULD work if the author hadn't hidden the passed variable by declaring a local variable of the same name. OFCOURSE this isn't going to work, ignore the following example cited from above for clarity.
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the passed object is HIDDEN FROM SCOPE by the local declaration. Also, this is inside a method, so I think even calling this and super wouldn't clarify it properly.
If it weren't hidden locally in the method, then it would have changed the value of the object passed externally.
To accomplish the changing of a primitive variable in a method there are 2 basic options :
1) If you want to change values on a primitive in a different method you can wrap the primitive in a "java bean" object, which will be essentially like a pointer.
Or
2) You can use an AtomicInteger/AtomicLong class which are used to concurrency, when many threads might need to modify a variable....so the variables has to have state that is consistent. Theses classes wrap primitives for you.
Warning : you are usually better off returning the new value, rather than setting/editting it internally in a method, from a maintainability standpoint ..
One quick way to achieving simulate passing by reference is to move the arguments to member variables of the enclosing class.
Although there are multiple ways to do it such as using a class or array wrapper or moving them to the function return type, the code may not turn out clean. If you are like me, the reason to ask such a question is that a piece of Java code has already been coded in a C++ way (which does not work) and a quick fix is needed. For example, in a recursion program such as depth-first-search, we may need to keep multiple variables in the C++ recursion function's argument list such as search path, flags whether the search should end. If you are in such a situation, the quickest fix is to make these argument variables into class member variables. Take care of the variable life cycle though and reset their values when necessary.
Java uses pass by value for everything.
As far as I understand you are not really sure if you can modify a variable passed in.
When you pass an object to a method, and if you use that object within that method, you are actually modifying that object. However you are modifying that object on a copy of it which still points to the same object. So actually when you pass an object to a method, you can modify it.
Once again, everything in java is pass by value.period.
In a class, I have:
private Foo bar;
public Constructor(Foo bar)
{
this.bar = bar;
}
Instead of creating a copy of bar from the object provided in the parameter, is it possible to include a pointer to bar in the constructor such that changing the original bar changes the field in this object?
Another way of putting it:
int x = 7;
int y = x;
x = 9;
System.out.print(y); //Prints 7.
It is possible to set it up so that printing y prints 9 instead of 7?
When a variable is used as argument to a method, it's content is always copied. (Java has only call-by-value.) What's important to understand here, is that you can only refer to objects through references. So what actually happens when you pass a variable referring to an object, is that you pass the reference to the object (by value!).
Someone may tell you "primitives are passed by value" and "non primitives are passed by reference", but that is merely because a variable can never contain an object to begin with, only a reference to an object. When this someone understands this, he will agree that even variables referring to objects are passed by value.
From Is Java "pass-by-reference" or "pass-by-value"?
Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references passed by value.
From http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
In Java, there is no counter part to the C++ "reference type" for primitives.
Your last example works that way because int is a primitive, it is copied by value. In the first example, "this.bar" would hold a copy of the reference (sort of pointer) to bar. So if you change the original bar (internally), the change will be reflected in your class. Try it.
To get that behavior you could modify a member of an object:
public class Number{
int value;
Number(int value){
this.value = value;
}
public String toString() {
return "" + value;
}
}
You could then do:
Number x = new Number(7);
Number y = x;
x.value = 9;
System.out.println(y);//prints 9
Java never copies objects. It's easiest to think of in terms of for each "new" you will have one object instance--never more.
People get REALLY CONFUSING when they discuss this in terms of pass by reference/pass by value, if you aren't amazingly familiar with what these terms mean, I suggest you ignore them and just remember that Java never copies objects.
So java works exactly the way you wanted your first example to work, and this is a core part of OO Design--the fact that once you've instantiated an object, it's the same object for everyone using it.
Dealing with primitives and references is a little different--since they aren't objects they are always copied--but the net effect is that java is just about always doing what you want it to do without extra syntax or confusing options.
In order to keep the original value of member bar, you will need to implement Cloneable interface. Then before assigning a new value to the object, you will need to make a clone of it and pass the cloned value and assign new values to the cloned object. Here is a tutorial on how to do it http://www.java-tips.org/java-se-tips/java.lang/how-to-implement-cloneable-interface.html .
this might be stupid question, but:
When I moved from ASM to C (no, I am not actually that old, I just started to love programing on MCU), I LOVED the way heap memory is used. Malloc was my friend, and I quickly became familiar with pointers. BUT...
Than I moved to OOP and Java. And actully, despite I donĀ“t like Java as a runtime, I love its language. Now, I would like to combine both, speed and memory management capabilities of C and the beauty of OOP. So I started to learn C++.
My problem is, in Java I was used to access class members and functions with . operator. In C++, I have to use somehow not so nice and easy to type -> operator.
So, my question is, is there some way you can use . operator instead of -> to access class members of object allocated on heap? Becouse, stack is limited, and the true power of OOP is in dynamic creation of objects. Remaining "differences" are OK :) . Well, maybe C++ yould allow you to define class methods inside class, but no one can have everything, right? :D Thanks.
Class &c = *c_ptr; // dereference pointer
https://isocpp.org/wiki/faq/references
Sure. Just get a reference to some object allocated on the heap (or the stack, but that's beyond scope):
Object* my_obj_ptr = SomehowGetHeapObject();
Object& my_obj = *my_obj_ptr;
...then you can use the dot operator on the reference:
my_obj.Foo();
Perhaps a pertinent question would be, why is this throwing you off?
No, that is not posssible, at least without some syntax changes. You can use (*Pointer).Function, which Pointer->Function is just a synonym for, but I think the latter is more comfirtable (that's why it exists).
EDIT: Or as the other posts say, just store the dereferenced pointer in a reference. Haven't thought about that, as the whole question is a bit strange.
In C++ there are two ways to access members of an object, depending upon how you are holding the object. If you have the object directly (or have a reference to it), you use the dot operator, .. If you have a pointer to the object, you use the pointer operator ->.
Consider:
class C;
...
// creates a new copy of "c" on stack
int f(C c) {
c.something = c.else;
}
// creates a reference to caller's "c"
int f(C& c) {
c.something = c.else;
}
// creates a pointer to caller's "c"
int f(C* p) {
c->something = c->else;
}
So, your problem is this: you have a pointer, but you don't like the pointer operator. Frankly, I don't really see this as a problem, you should just use the pointer operator until you like it. But, this is SO, so here is a solution.
Initialize a reference from your pointer, and use the reference instead:
int f(C* p) {
C& c = *p;
c.something = c.else; // update the object pointed to by 'p'
}
Or, to make it feel even more natural:
int f2(C& c) {
c.something = c.else; // updates f1's object
}
int f1() {
C* p = new C;
f2(*p);
delete p; // don't forget this step!
}
What's your deep comprehension of pointer,reference and Handle in C,C++ and Java?
We usually think about the pointer,reference and Handle on the specify language level, it's easy to make confusion by the newbie like me.
Actually all those concept in java, just a encapsulation of pointer.
All pointer just a encapsulation of main memory addresses .
So all of those ,just a encapsulation wiles.
all above, it's my personal glimpse. And what's your comprehension ?
welcome to share with me.
Each language has differences to this respect. In C there are only pointers that are variables holding a memory address. In C you can use pointer arithmetic to move through memory, if you have an array, you can get a pointer to the first element and navigate the memory by incrementing the pointer.
Java references are similar to pointers in that they refer to a location in memory, but you cannot use pointer arithmetic on them. Only assignments are allowed. Note that the reference is not the object, but a way of accessing an object. This can be seen in argument passing semantics: objects are not passed by reference, references are passed by value:
public static void swap( Object o1, Object o2 )
{
Object tmp = o1;
o1 = o2;
o2 = tmp;
}
The previous piece of code is a complex no-op. References to two objects are passed by value, they are played with inside the method and nothing happens from the caller perspective: the real objects do not suffer any change, nor do the references the caller has into those objects. That is, if the call is swap( ref1, ref2 ), the system will make copies of the references into o1 and o2, the copies are changed within the method, but the caller variables ref1 and ref2 will remain unchanged after the method call.
In C++ you have two concepts: pointers are the same as C pointers and close to Java references, while C++ references are aliases into the objects they refer. C++ references can only be initialized with one object/data element in construction and from there on, using the original object and the reference is exactly the same. Besides the fact that references don't hold the resource and thus the destructor will not be called when the reference goes out of scope, nor will the reference notice if the referred object is destroyed, for all other uses the two names are the same element.
template <typename T>
void swap( T & a, T & b )
{
T tmp( a );
a = b;
b = tmp;
}
The code above in C++ differs from the Java version in that it does change the caller objects. If a caller uses swap( var1, var2 ), then the references are bound to those variables, and it is var1 and var2 the ones that suffer the change. After the call, the value of var1 and var2 is actually swapped.
Handles are in a different level, they are not language construct but tokens provided by a library so that you can later on refer to some resource that the library manages internally. The most general case are integer handles that are ids (or offsets) into a resource table, but I have seen strings used as handles. It is the library internally who decides what is exactly a handler (a pointer, an integer, a string or a more complex data structure). Handles are meant to be opaque in that the only sensible use is to store them and later give it back to the same library as part of other function signatures.
In C++ a pointer is a variable that points to a location in memory. You can access the object or data stored there by dereferencing the pointer. A reference is simply a pointer that has two distinctions from a pointer. First, you cannot change what a reference points to once the reference is initialized. Second the dereferencing semantics are removed so you can access a reference as if it were an object allocated on the stack instead of on the heap with new.
In Java, there are no pointers, only references. Every object you use is a reference to an object allocated on the heap. The downside is you can't do pointer math tricks. That's also the upside.
EDIT:
As pointed out in the comments, a Java reference differs from a C++ reference in that it can be reassigned once initialized. They are still called 'reference types' by the language specification, but behaviorally they act like pointers in terms of being able to be reassigned and passed to functions, but the semantics of dereferencing them look like non-pointer access looks in C++.