I have experience working in Java but have recently started doing work in C++, I'm having a little trouble understanding how things are stored in memory in the latter. In java, the following is valid:
class Class {
int myInt;
public Class(int myInt) {
this.myInt = myInt;
}
}
So I have an integer within the class, I give it a value when the object is created. I want to replicate this in C++:
class Class {
int myInt;
public:
Class (int myInt) {
// What goes here?
}
};
This however doesn't work. If I name the variable being passed into the constructor something other than myInt, I can simply state myInt = differentName. But suppose like in the Java, I want both the variable passed to the constructor and the name of the variable to be the same? How can I achieve this?
Two options:
Using an Initializer list:
class Class {
int myInt;
public:
Class (int myInt) : myInt(myInt)
{
}
};
What you were intentionally looking for:
class Class {
int myInt;
public:
Class (int myInt)
{
Class::myInt = myInt;
}
};
But the first one is preferred.
You just need to use the constructor initialization list:
class Class {
int myInt;
public:
Class (int myInt) : myInt(myInt)
{
// by the time you get here, myInt is already initialized.
// You can assign a value to it or modify it otherwise,
// but you cannot initialize something more than once.
}
};
That the only way to explicitly initialize a data member in a constructor. Once you're in the body of the constructor, all data members have been initialized.
In addition to the initializer syntax, this is also available in C++. You would use it as this->myInt because this is a pointer.
"this" is a pointer in C++. So it'll be
this->myInt = myInt;
The following is the way to achieve the same in c++
this->myInt = myInt;
Related
With java you can do :
Integer i = 2;
Is it possible to make such "constructor " instantiation + initialization for my own classes ?
That's not a constructor, that is an example of autoboxing. The short answer is no. The longer answer is yes, if you're willing to write and run a precompiler (or preprocessor) for your project.
This is not actually a constructor. What this is doing is assigning the int literal 2 to an Integer variable.
Just like assigning the return value of a function to a superclass variable.
i.e. Person p = getEmployee(7);
If I understand what you are saying, you want constructors with default values.
Below is an example:
public class MyClass {
private int i;
public MyClass() {
this(2);
}
public MyClass(Integer i) {
this.i = i;
}
}
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
Lets say this is the C++ code:
void change(int& x){
x++;
}
or
void change2(int* a){
*a++;
}
Both will change the global x, right?
So how can I do something like that in java?
Specifically, I want to point to a Vector object
But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.
Thanks for
help!
In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.
Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:
void change(MutableInt x) {
x.increment();
}
The change to x will be visible to the caller.
Specifically, I want to point to a Vector object
When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.
Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.
With Java you cannot pass primitive types like int by reference, they are passed only by value.
The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.
Use an array of single value, like this
int[] value = new int[1];
value[0] = 2;
// call a method
obj.setValue(value);
// and in setValue
public void setValue(int[] value) {
value[0] = 5;
}
Or second approach use an holder class:
public class Holder<T> {
public T value;
public Holder(T value) {
this.value = value;
}
}
// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);
obj.setValue(h);
// and in setValue
public void setValue(Holder<Integer> h) {
h.value = 5;
}
In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:
public class IntHolder {
public int value;
public IntHolder(int value) {
this.value = value;
}
}
Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.
Thusly:
public int change(int x) {
return ++x;
// or
// return x + 1;
}
To test it:
int x = 2;
change(x);
System.out.println(x); // returns 2
x = change(x);
System.out.println(x); // returns 3
So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.
Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:
public class MyInt() {
public int i;
public void setInt(int i) {
this.i = i;
}
public int getInt() {
return this.i;
}
public int increment() {
this.i++;
}
}
You need to change your change function to have the above MyInt object as argument:
public void change(MyInt i) {
i.increment();
}
Usage:
MyInt x = new MyInt();
x.setInt(2);
change(x);
System.out.println(x.getInt); // returns 3
In your case you want to change a Vector object...
public void changeVector(Vector v) {
// anything you do with 'v' will change it even
// for the scope that called this method
}
// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method
Hope this all makes sense.
Both will change the global x, right?
So how can I do something like that in java? Specifically, I want to
point to a Vector object
The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?
Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)
public class Foo {
private static List<Integer> globalVector = new Vector<Integer>();
public static void add(int number){
globalVector.add(number);
}
// ... plus whatever other accessors to the global list that you need
}
Anywhere else in code:
Foo.add(23); // modifies the global vector
(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)
While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:
public class IntPointer {
public int value;
public IntPointer(int value) {
this.value = value;
}
}
Then elsewhere you could say:
public static void change(IntPointer ipoint) {
ipoint.value++;
}
public static void main(String[] args) {
IntPointer a = new IntPointer(10);
change(a);
}
This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:
public class ABPair {
private int a = 0;
private int b = 0;
public static void changeA() {
a++;
}
public static void changeB() {
b++;
}
}
So that elsewhere I can say:
public static void main(String[] args) {
ABPair ab = new ABPair();
if (ACondition) {
ab.changeA();
}
}
In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.
Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.
The major differences between a pointer in C and a reference in Java are:
You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one).
You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object.
For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).
So in a way Java references could be called "restricted pointers".
public class Foo {
public int a = 3;
public void addFive(){
a += 5; System.out.print("f ");
}
}
public class Bar extends Foo {
public int a = 8;
public void addFive(){
this.a += 5;
System.out.print("b " );
}
}
public class Test {
public static void main(String args[]){
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}
I am getting output b 3 .why it is not giving b13 as output.Can anyone please explain.
Assuming class Foo is declared as below
class Foo
{
public int a = 3;
public void addFive()
{
a += 5;
System.out.print("f ");
}
}
Variables have no concept of overriding. They are just masked.
It is printing 3 because, when you use a superclass reference to access a variable, it accesses the variable declared in superclass only. Remember that superclass doesn't know anything about subclass.
class Foo {
public void addFive() {
a += 5; System.out.print("f ");
}
}
you don't have 'a' variable defined, so this example doesn't even compile.
correct code:
class Foo {
public int a;
public void addFive() {
a += 5; System.out.print("f ");
}
}
and see link https://stackoverflow.com/a/2464254/1025312
I assume that you meant to declare an integer field a in class Foo.
The answer to your question has to do with concepts of 'overriding' and 'hiding', as others have pointed out. Another way to explain it is that for member variables, there is no such thing as 'dynamic dispatch'. What that means is that, if you access a member of a certain object, the system checks at run time which member you mean, by looking at the class hierarchy.
So, when calling the method f.addFive, at run time, the system will see that your object is actually a Bar and not a Foo, and so take the addFive function that you defined in the Bar class.
That does not happen for member variables: you access f.a in your print statement, and at compile time it is decided that right there you want to access the field a declared in class Foo there -- and so, that is what will happen at run time.
Now, the reason that there is no dynamic dispatch for member variable access is performance: it would be very expensive to go through the whole 'see what object this really is' logic every time you just want to add some value to a member variable.
Declaring public int a = 8 in Foo class instead of Bar class it should work... printing B 3.
But I suppose you are talking about a question included in the Java certification exam, so you have to correct the code of the Foo class adding public int a = 3.
You cannot override a variable in Java, but declaring in as public (or protected) in the super-class you can use it also in all inherited classes.
In this case the right output is B 13 because in the test class you are using a Bar object as a Foo object, so the value of a is 3 and not 8.
I'm learning to do some Java 101 syntax stuff. In an exercise I'm trying to do, I can't get the incremented value to print. Any ideas?
Here is my code:
class StaticTest {
static int i = 47;
}
class incrementable {
static void increment() { StaticTest.i++; }
}
class DataOnly {
int i;
double d;
boolean b;
public static void main (String[] args) {
incrementable t = new incrementable();
DataOnly df = new DataOnly();
df.i = t.increment();
System.out.println(df.i);
}
}
The error I get is:
aTyp0eName.java:18: incompatible types
found: void
required: int
df.i = t.increment();
df.i is an int and so is t.increment. I'm guessing it's because increment() is void?
your method signature is:
static void
Which means nothing is returned from this method.
Hence, attempting to assign increment() to df.i won't work.
increment() doesn't have a return value. You'd need to have it return an int for your code to work:
class incrementable {
static int increment() {
StaticTest.i++;
return StaticTest.i;
}
}
"void" is a keyword reserved for methods which don't return any value. Otherwise, you specify what class or primitive you return (int, double, String, whatever). You can read more about return values here.
Also, for future reference, class names should be capitalized, so you should be using "Incrementable" rather than "incrementable". (In my sample code I kept it the same as you had it so you could just drop the code in for now.)
The error I get is:
aTyp0eName.java:18: incompatible types
found: void
required: int
df.i = t.increment();
df.i is an int and so is t.increment [fault?]. I'm guessing it's because increment() is void?
Eeeexactly, your guess is correct.
This is the error message explained line by line:
aTyp0eName.java:18: incompatible types
You are trying to assign "void" to an int in line 18.
df.i = t.increment();
Here is where the error is.
found: void
You declare what's the return type in the method "signature".
The method signature is :
<access modifiers> <return type> <method name> (<parameters> )
static void increment ()
So the return type is void.
Next line:
required: int
df.i is int as you have previously stated.
So, pretty much you have already your own question answered.
The good point of having a compiler is that it tells you when something is wrong.
The bad thing ( for humans ) you have to learn to read those messages. They vary from programming language to another and even from compiler to compiler.
This would be a corrected version:
class StaticTest {
static int i = 47;
}
class Incrementable {
static int increment() {
return ++StaticTest.i;
}
}
class DataOnly {
int i;
double d;
boolean b;
public static void main (String[] args) {
Incrementable t = new Incrementable();
DataOnly df = new DataOnly();
df.i = t.increment();
System.out.println(df.i);
}
}
There are some other enhancements could be done, such as adding access modifiers to the methods and attributes, but for now I think this would help.
The answer is that the increment() method returns a void. That being said, there are a lot of violations of the Java standard syntax that programmers generally use, Namely:
Class names should start with a capital letter.
fields should not be mutated from different classes, rather a helper method should be within the same class
If you want to call a static method, don't reference an instance variable, rather use ClassName.reference
If a variable is only needed locally, it should not be a field (df.i could just be an int i declared within the main method).
EDIT:
An example of a helper method within the same class:
class StaticTest {
private static int i = 47; //keep i private and mutate and access via methods
public static void increment() { i++; }
public static int getI() { return i; }
}
also, if you instantiate incrementable, you shouldn't define the method increment() as static. or you can, but don't need to.
you could simply incrementable.increment() if it's static.
just a tip. as for the answer to your question, toolkit already said that right.
Also, your incrementable class should really be Incrementable.