Create an inline object and pass as parameter - java

Hi I come from Java where the following is valid:
System.out.println(new String("Hello World"));
is there a C++ equivalent to passing creating an object or pointer in the constructor and pass it as a parameter at the same time such as.
heap.insert(new Food);

Yes. For example
std::vector<Food> c;
c.emplace_back(constructor arguments for Food);
In general, it is most often the case that objects are not given to method as pointers.
If heap.insert takes a const reference :
void insert(const Food& val);
then you can use it with temporary or existing Food arguments, such as
heap.insert(Food{});
var auto foo = Food{constructor arguments};
heap.insert(foo);
heap.insert(Food(constructor arguments));
or in some cases even
heap.insert({constructor arguments});

heap.insert(new Food);
in of itself is valid C++ syntax. It constructs a new instance of the Food class, and passes it to heap's insert() method.
However, the key fundamental difference you will need to learn when transitioning from Java to C++ is that your C++ application is completely responsible for managing all object's lifetimes. In Java you don't need to think about it. Once an object is no longer referenced anywhere, at some point it'll get destroyed by Java's garbage collector.
C++ makes you responsible for managing each object's lifetime. Whenever your application does not need the object that you constructed here with the new operator, it should be deleted, otherwise you're going to leak memory.
To summarize:
heap.insert(new Food);
is just half the story. The new operator will construct your new class instance, and your heap object's insert() method, presumably, stores the pointer to the new class instance, in some fashion. Somewhere, you will then need to delete that class instance, sooner or later.

Yes. You have to define a class, a constructor for it that accepts parameters, then a function that accepts instances of that class and that's all.
Eventually, add to the class definition a proper copy constructor or pass it by reference.
It follows an example:
struct S {
S(int x) { this->x = x; }
int x;
};
void fn(S s) { }
void cfn(const S &s) { }
int main() {
fn(S{42});
cfn(S{42});
}
Be aware that using new in such a case is one of the easiest ways to incur in a memory leak, so pay attention!!

The examples you gave are too easy.
cout << string("hello World");
// not necessary to contruct a string, but to show that it can be done on the spot
heap.insert(Food()); // construct a Food on the spot...
But in general, if you are talking about anonymous classes and similar things in Java, C++ has this stuff, and it has also the lambda concept which is very powerful ;)

If the function parameter is by value or by const reference, and the type you are passing can be used to construct the object, you can pass it directly. For example:
void print(const std::string& str);
int main()
{
print("Hello world");
}
std::string has a constructor which can accept the string literal, and therefore the code compiles, creating a temporary string object, equivalent to:
print(std::string("Hello world"));
If the constructor takes multiple parameters, you can create a temporary object directly in the function call. For example:
void myfunc(const MyClass& c);
myfunc(MyClass(param1, param2));
In Java new objects are creating using new. In C++, new is not required to create a new object, and should be avoided as much as possible, because it makes it harder to avoid memory leaks. This is one of the most common mistakes programmers coming from Java make.
std::string text;
MyClass c;
c.do_something();
This code is totally valid. text and c are valid objects.
std::string *text = new std::string();
MyClass *c = new MyClass();
c->do_something();
delete text;
delete c;
This code is also valid*. But it takes more typing, and if you forget to delete them, you will get a memory leak.
*Edit: Actually it is not exception safe! All the more reason to avoid new!

Related

How do I create an object within method sending reference as a parameter [duplicate]

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.

Best strategies when calling a method that should modify more than one variable

I am pretty new to Java, I have to convert C/C++ code to Java and I am running into obstacles. Because of the way variables are passed to the methods, their modification in the method is not straightforward, and I have no idea what is the most reasonable approach to take. Sorry for the pseudocode examples, I hope they will clearly explain what I am talking about without delving into unnecessary details.
I need something that would be equivalent to C
ModifyMyString(type1 &t1,type2 &t2);
(return type doesn't matter, it can be void) as I need the function to modify both t1 and t2.
I can easily modify one of the variables, say t1, by declaring in Java
type1 modifyMyString(type1 t1, type2 t2);
and assigning the returned value to
t1 = modifyMyString(t1,t2);
but it is only half of a success, as the new value of t2 is lost.
I can declare new class
class JustToPassTwoVariables {
type1 t1;
type2 t2;
JustToPassTwoVariables(type1 tt1, type2 tt2) { t1 = tt1; t2 = tt2; }
}
and do something like
JustToPassTwoVariables jtptv = modifyMyString(JustToPassTwoVariables(t1,t2));
but I feel like it is clumsy and makes the code unreadable.
In desperation I could also resign the idea of using a modifyMyString method, and repeat all the code locally in each place I would call modifyMyString - but it makes even less sense than using JustToPassTwoVariables class.
Is there a correct (or at least widely used, accepted as a standard, whatever) strategy to code such things in Java?
The recommended way in java is (in some people's opinion the clumsy way) to create a class containing the two fields and return an instance of that class.
I feel that it is much less clumsy if you stop and think about what the method is actually doing, and taking care to properly name both the method and the class returning the two values.
The simple answer is no. This sort of feature is not allowed in Java.
The correct way to do it is to pass in the object to be modified not the two variables. After all in virtually all cases those variables are already wrapped in an object, in cases where they aren't they often easily can be.
Either split the function into two functions and call it once for each variable, or wrap the variables into an object and pass that object into the function.
Don't forget Java allows Inner Classes which makes this sort of thing less painful.
You can't return two values from a method in java. The way is to return an object and set all the values in it. i.e. In your case, you need to create a value container class i.e. say Result class that will have two fields storing the type1 and type2 value in it. The return type of the method would be of value container object type i.e. say Result instance with two fields in it - type1 and type2
Example :
Result result = modifyMyString(t1,t2);
result.getT1(); //gets t1 value
result.getT2(); // gets t2 value
Please learn about setters and getters in Java to work on the class or object level fields
In Java if you want to do this you would generally make type1 and type2 into object whose values can be modified. The method can then modify the values of the parameters to get the desired effect. For example :
void myMethod(type1 arg0, type2 arg1) {
arg0.setValue(newValue0);
arg1.setValue(newValue1);
}
If type1 and/or type2 do not have any way of changing their values (e.g. they are of type String) then you would either make a wrapper class for each of them e.g.
class Type1Wrapper {
private type1 type1;
type1 getType1() {
return type1;
}
void setType1(type1 newType1) {
type1 = newType1;
}
}
or you would make a wrapper for both of the types simultaneously like you have in your question (although the method return type will be void and the method will modify your wrapper's values)
There are several methods to modify a group of objects "of the same type/class". The simplest of them being, add them to a "list" pass that list to your modification function, do whatever modifications/additions/deletions etc.. The list reference will be automatically available outside with the "changes made in the called function" .
So, you can do
List<String> l = new ArrayList<String>();
l.add("Hello");
l.add("world");
ModifyMyString(l);
// here also l = "hello" , "world" , "added"
public void ModifyMyString(List l)
{
l.add("added"); // now l = "hello" , "world" , "added"
}
Java is an OO language so to get the best out of it you should look to an OO solution. It's hard to give you a definite solution with this abstract example but this is how I would approach this.
You mention that t1 and t2 both need to be updated by this modify procedure/method. Also that they need to be updated at the same time, if they were unrelated then you could just call modify on each string in turn. If these two strings are related like this then it's likely they belong to the same type.
So we need a class containing type 1 and type 2.
public class TypeContainer
{
private String type1;
private String type2;
.. getters and setters
}
Obviously you'll want a better class name.
You suggest something similar yourself but call it JustToPassTwoVariables. This is missing the point of OO. You could write a simple wrapper like this and pass it to some other method to modify the values but a more OO approach would be to add the modify method to this class itself.
...
public void modfiy(String val1, String val2)
{
type1 = val1;
type2 = val2;
}
...
I'm not sure what your modify is trying to do but in this case I would probably have these as two separate setter methods. This is quite an abstract example!
Basically I would avoid having the modify method in some other unrelated class. You should look to group common related attributes into classes and then write methods in those classes for any actions you need to take (such as modify).
Trying to convert a procedural C program into an OO Java program sounds like a PITA. It's a complete paradigm shift. Having said that I have seen automated conversions which while technically Java are still very procedural. Not very pretty and hard to maintain but was done for political reasons.
Java discourages this strategy beacause in-variable should be immutable, but if you have to migrate from C/C++/C# and you have a lot of "void function with parameters passed as in/out", you can create a Custom "Reference" class like this and you can incapsulate the original object.
public class CustomRef {
public Object internal;
public CustomRef(Object object) {
this.internal=object;
}
}
then when you call
CustomRef ref1= new CustomRef(myParams1);
CustomRef ref2= new CustomRef(myParams2);
myFunction(ref1, ref2);
myParams1 = ref1.internal;
myParams2 = ref2.internal;
the function is
void myFunction(CustomRef ref1, CustomRef ref2) {
Object param1 = ref1.internal
// a lot of code
ref1.internal = param1;
}
really discouraged way ... such as using ArrayList, arrays [] to "pass by reference".
NOTE: this way is a waste of resource; CustomRef instance should be reused through object pool (another discouraged way).
I would use a StringBuffer. You can initialize it with a String and convert it back to a String

Java equivalent of C++ copy assignment operator

I'm trying to understand this operator function written in C++ and convert it to Java.
Class& Class::operator=(const Class& In) {
properties = In.properties;
return *this;
}
Does this simply copy instance and properties of a class object? For which I've already written something:
public static Class copy(Class obj) {
//returns new instance of Class individual
Class copy = new Class(obj.row_num, obj.col_num, obj.input_length, obj.output_length, obj.max_arity, obj.function_length, obj.levels_back);
copy.genes = obj.genes.clone();
return copy;
}
Am I on the correct track? Many thanks for your help.
Ampersand & designates a reference in C++. It is needed to provide the behavior similar to what Java objects provide "out of the box", because Java manages objects through references.
There is no copying going on in C++ when a reference is passed. In fact, avoiding copying is a major reason for using const references as function parameters.
The code that you show does not perform copying either: it changes its state based on the value being "assigned". The closest way of modeling this in Java would be providing an assign(Class other) method that changes the current state to match that of the object passed in:
Class assign(Class other) {
this.properties = other.properties;
return this;
}
You will need to use this method in place of C++'s assignment, like this:
Class clOne(args1);
Class clTwo(args2);
clOne = clTwo; // Using the assignment operator
becomes this:
Class clOne = new Class(args1);
Class clTwo = new Class(args2);
clOne.assign(clTwo); // Using the assignment method instead of the operator
You're pretty much on the right track. The copy assignment operator in C++ is used when directly assigning (copying) from one object to another. As Java objects are only accessible via references, such assignments are meaningless. To match the C++ semantics exactly, the Java equivalent would be:
public Class copy(Class obj) {
row_num = obj.row_num;
col_num = obj.col_num;
// etc., etc.
genes = obj.genes.clone();
return this;
}
Am I on the correct track?
Kind of. But not quite. C++ distinguishes between reassigning an existing object and creating a new one.
Java doesn’t. You cannot reassign to an existing object in Java1 (but you can of course reassign a reference). In Java, in order to copy an object (rather than assign a reference to it), you would usually use a copying constructor:
Class(Class other) {
// Copy members of `other` into `this`.
}
And then use it as follows:
Class x = new Class(something here);
Class y = new Class(x); // copy
In particular, this is what all the Java containers implement. I would not rely on clone. First of all, clone should only be used if the class implements the tag interface Cloneable. Second of all, clone’s design is arguably broken and its use is not recommended.
1 Well you could of course reassign the members of an object (unless they are final), and you could mimic C++’s copy assignment operator by providing a method assign to do that. However, this isn’t the conventional way of doing things in Java (although it might have its place in some exceptional instances).

How do I pass a primitive data type by reference?

How can I pass a primitive type by reference in java? For instance, how do I make an int passed to a method modifiable?
There isn't a way to pass a primitive directly by reference in Java.
A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:
public class IntRef { public int value; }
But how about some pre-built wrapper classes, so we don't have to write our own? OK:
The Apache commons-lang Mutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
The java.util.concurrent.atomic Atomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.
Length 1 primitive array
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?
Also see
The answers to StackOverflow question "Mutable boolean field in Java".
My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.
Nothing in java is passed by reference. It's all passed by value.
Edit: Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:
String a;
int b;
doSomething(a, b);
...
public void doSomething(String myA, int myB) {
// whatever I do to "myA" and "myB" here will never ever ever change
// the "a" and "b"
}
The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.
With a holder:
private class MyStringHolder {
String a;
MyStringHolder(String a) {
this.a = a;
}
}
MyStringHolder holdA = new MyStringHolder("something");
public void doSomething(MyStringHolder holder) {
// alter holder.a here and it changes.
}
With return value
int b = 42;
b = doSomething(b);
public int doSomething(int b) {
return b + 1;
}
Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short> if necessary too.
Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).
That's not possible in Java, as an alternative you can wrap it in a single element array.
void demo() {
int [] a = { 0 };
increment ( a )
}
void increment( int [] v ) {
v[0]++;
}
But there are always better options.
You can't. But you can return an integer which is a modified value
int i = 0;
i = doSomething(i);
If you are passing in more than one you may wish to create a Data Transfer Object (a class specifically to contain a set of variables which can be passed to classes).
Pass an object that has that value as a field.
That's not possible in Java
One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.
On the other hand, you can just use code like:
int a = 5;
a = func(a);
and have func return the modified value.

In Java, is new always new?

Is there any way in Java that a statement like
Thing thing = new Thing();
could not result in a new object being created (i.e. any way that thing could end up pointing to an already-existing object)?
The new operator allocates new heap space and calls the constructor. You will always get a new object that way (unless, as others pointed out, an Exception is thrown in the constructor).
The thing is a little different with static methods that return a reference, such as Integer.valueOf() which re-uses objects from an internal pool if possible.
If the constructor for Thing throws an exception, the object isn't created. However, thing will never point to another existing instance of Thing.
Several people are saying that an object won't be created if the constructor throws an exception. I would just like to point out that this is not true. As an example, take a look at this very bad code:
public class Test {
static int count;
static Set<Test> set = new HashSet<Test>();
int id = count++;
public Test() {
set.add(this);
throw new RuntimeException();
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 5; i++) {
try {
new Test();
} catch(Exception e) {
}
}
System.out.println(set);
}
public String toString() {
return "Test[" + id + "]";
}
}
The output is:
[Test[0], Test[1], Test[2], Test[4], Test[3]]
new creates a new object EVERY TIME.
Using new will always result in a new object being allocated and created. However, you might be referring to the concept of interning, where objects and stored in a pool and can be reused to save on space. For a good example, see this article on String interning in Java.
New is always new (maybe with some exceptions for primitive wrappers), but if reusing objects is a desired behaviour there are ways to do that through certain design patterns (singleton, factory, pool etc.).
I'm not sure if I understand your question correctly.
The definition of new is to allocate and initialize a new object.
I guess you might be able store a static reference to a object, and then clone it to make a new object, but that object would still be new.
Since you cannot modify the value of this (otherwise you could just say something like this = oldObject in your constructor), the only way you could do this is to throw an exception, like has been mentioned before.
as far as I know it's not like C++ where you can overload operator new or do placement new or other allocator things. (but I'm not familiar with the JLS)
new always creates new object. In java you can't reuse object using new. Really this leads to performance issue in certain java class. For e.g. Boolean class can practically stores only two values (true or false), still a user can create multiple objects with same value using new.
No, in the case there's no space in memory for it, you should get an OutOfMemoryError.
Of course, there could be other exceptions thrown by the Thing constructor.
No.
After executing that line of code thing will never reference an object that existed before that line.
The call to new can fail if this is the first time you are referring to the class and if the class has static blocks that fail to initialize. I have experienced behaviors wherein any runtime errors that occur in a static block or constructor will result in the new call throwing a ClassNotFound Exception in the context of usage within the websphere application server. The websphere class loader apparently rejects the class from loading because of the runtime exception.
In Java, the only thing I can think of is using the Singleton pattern. This would not create multiple new instances of Thing, but rather an instance of the same object every time.

Categories

Resources