Array of objects, difference between Java and C++ - java

I am new to C++ and I am porting over a Java project to C++.
Consider the following Java code, where Piece is a class representing a chess piece:
Piece[][] myPieces = new Piece[8][8];
It creates an array where all the entries are null.
How can I achieve the same thing in C++? I tried:
Piece* myPieces = new Piece[8][8];
But this will create an array with all the entries initialized with the default constructor.
Thanks
Edit: I want the C++ code to be efficient/elegant and I do not care nor wnant to copy paste from Java to C++. I am happy to heavily modify the code structure if needed.
Edit 2: The code is for chess programm, the size of the array will never change and performance is critical.

The simplest way to declare an 8x8 array of optional objects in C++ is like so:
boost::optional<Piece> myPieces[8][8];
The boost::optional type represents an optional object (like your nullable references in Java) that doesn't have all the pitfalls of using pointer types. It should be available as part of the standard library in the next few years.
You may prefer to use the std::array type, which is an encapsulation of fixed-size arrays that allows them to be treated as first-class citizens and also provides a nicer interface:
std::array<std::array<boost::optional<Piece>, 8>, 8> myPieces;
If you want to be able to resize your arrays at run-time, consider std::vector instead.

As you want it performant, and right for C++ instead of a dumb translation, how about this:
Use a size-1 POD-type for piece.
Add all the convenience-methods you might want to it:
struct Piece {
unsigned char value;
constexpr Piece() : value() {}
constexpr operator bool() const {return !value;}
constexpr bool empty() const {return *this;};
constexpr bool black() const {return value&0x80;}
constexpr bool white() const {return value && !black();}
constexpr unsigned piece() const {return value & 0x7f;}
};
Now that would be an equivalent raw array:
Piece board[8][8];
Or use std::array:
#include <array>
std::array<std::array<Piece, 8>, 8> board;

The answer depends, because contrary to Java, in C++ you have different ownership semantics and object lifetime management (the two go hand in hand).
If you want to model objects similar to java, you would write:
using PiecePtr = std::shared_ptr<Piece>;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
The shared_ptr has similar semantics to a java object (pass it around wherever and it's lifetime is guaranteed as long as there are references to it).
If you want to model observed objects (i.e. the array doesn't own them), you should write:
using PiecePtr = Piece*;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
This ensures that when the Pieces object gets destroyed, the actual pieces themselves remain in memory.
If you want to model unique objects, owned by the Pieces array, you should use:
using PiecePtr = std::unique_ptr<Piece>;
std::array<std::array<PiecePtr, 8>, 8> Pieces;
This ensures that when the Pieces object gets destroyed, the actual pieces themselves get destroyed as well.

In C++ you'd do something like:
std::vector<std::vector<std::unique_ptr<Pieces>>> myPieces;

Semantically equivalent would be:
Piece* myPieces[8][8]
as java only knows objects on the heap, pointers.
As Piece probably is not a final class, but has King, Queen, this is the way to go.

In c++, newly created object (even in array) is created with default constructor. That's one of the important differences with java. If you want to call constructors individually, just use vector of vectors and add each one of them.

I have no experience with java but I believe from what I got that this could be a good replacement in C++:
std::array<std::array<unique_ptr<foo>, 8>, 8> arr = {};
if(arr[2][3].get() == nullptr) // Can check for null elements
std::cout << "this is null";
arr[3][4].reset(new foo()); // Initialize an element
smart pointer avoids memory leaks
std::array provides performances comparable to a normal C array
aggregate initialization provides each pointer a null value
fixed size as the java array

So you want to make a Chess engine and performance is critical. There are several online tutorials for this. Speed is important for a Chess AI so it can consider more moves per second, but you may need to sacrifice elegance for that.
You can either store the piece values in the board array directly, or store the pieces in a separate backing array and create the board as pointers to these pieces. There are some advantages to the second approach which I can't remember right now.
std::array<std::array<Peice *, 8>, 8> Board;
std::array<Piece, 32> Pieces;
You can represent an empty cell as a null pointer.
If you want everything in the same array, you can simply use
std::array<std::array<Peice, 8>, 8> Board;
But you will need to create a "dummy" piece value to represent an empty cell.
Note there is no dynamic memory allocation and the data is compact in memory so better cache performance.
Piece could be an enum or a struct with some useful getter functions, such as IsWhite.

In C++, you have to declare as:
Piece *** myPieces;
then, allocate as:
myPieces = new Piece **[8];
then,
for (int i = 0; i < 8; i++) {
myPieces[i] = new Piece *;
}
Now, if you do,
myPieces[0][0] = new Piece(); // C++, calls default constructor of Piece
In Java,
Piece[][] myPieces;
myPieces = new Piece[8][8];
now, if you do,
myPieces[0][0] = new Piece(); // Java, calls default constructor of Piece
Since you have 8x8 known already, you may also declare as (in C++):
Piece * myPieces[8][8]; // 64 pointers preallocated as 8 rows, 8 cols
then,
Now, if you do,
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
myPieces[i][j] = new Piece(); // or new Pawn or new Knight etc, subclass of Piece
}}
or allocate as needed e.g.
myPieces[0][0] = new Piece(); // or new Pawn or new Knight etc, subclass of Piece

Related

Is there any pre-defined method to swap two elements?

If we have to swap two elements in java then we can swap them using a temporary variable.
int temp=a;
a=b;
b=temp;
Also, we can do it by using different ways also but is there any predefined method like C++ that have std::swap()?
In the collection, we have swap() but it only works for the list.
No, there is no pre-defined function that swaps two elements. And for good reason. Java is always pass-by-value. Not like C++, where you can choose whether to give the value or the reference of the variable to the function.
If you want to read more about pass-by-value / pass-by-reference, this answer covers pretty much everything.
No, there is no way to do that without using a temporary variable.
Even C++ implementation of std::swap() uses a temporary variable inside, see here.
If you really want to you can wrap this code in a method and just call it.
This is just for fun but if you really want to swap integers, you can do it like so:
int a = 100;
int b = 25;
a = a + b;
b = a - b;
a = a - b;

reducing Java Garbage Collection for methods returning arrays?

Object A has method B(), and lives for most of the life of the application. B calls object C method D(). D() returns an array holding up to x MyData objects. MyData might be a POD (plain old data)/PDS (passive data structure) or might be more, but a MyData can be reused by calling methods or setting fields; its identity or functionality isn't cast in stone during construction or otherwise.
Currently B() is defined like:
class A {
public B() {
MyData[] amydata = c.D( 5 );
:
:
}
}
Currently D() is defined like:
MyData[] D( int iRows ) {
MyData[] amydata = new MyData[ iRows ];
for ( int i = 0; i < iRows; i++ ) {
if ( no more data )
return amydata;
amydata [ i ] = new MyData();
// calculate or fill in MyData structure.
}
return amydata;
}
A is going to be always, or for a long time (e.g., until the user reconfigures it) be asking for the same number of rows, even though the data will differ.
So what if I have the caller pass in the array reference:
class A {
int iRequestSize = 5;
int iResultSize;
MyData[] amydata = new MyData[ iRequestSize ];
public B() {
iResultSize = c.D( iRequestSize, amydata );
:
:
// use up to iResultSize even though array is potentially bigger.
}
}
// returns number of rows actually used
int D( int iRowsMax, MyData[] amydata ) {
for ( int i = 0; i < iRowsMax; i++ ) {
if ( no more data )
return i;
if ( amydata [ i ] == null )
amydata [ i ] = new MyData();
// calculate or fill in MyData structure.
}
return iRowsMax;
}
I'm a C++ guy and new to Java, but it seems that assuming MyData can be recycled like this, the second version should avoid creating and copying MyData's, as well as eliminating garbage collection?
I would say the second variant is worse.
In the first variant amydata and all the objects referenced by it can be garbage collected as soon as the method B() exits (assuming that B doesn't store a reference to amydata somewhere else.)
In the second variant amydata cannot be garbage collected as long as the instance of A lives.
Consider the case where upon the first call to D() it returns 5 references to MyData objects, but on subsequent calls it returns no more rows. In the first variant the amydata array and the 5 referenced MyData objects can be garbage collected as soon as B() returns. But in the second variant neither the amydata array nor the 5 MyData objects referenced through it can be garbage collected - possibly never during the whole runtime of your application.
Remember: the Java Garbage Collector is optimized for many short-lived objects
Disclaimer: Reading the OP's comments, I have to admit that I didn't get his real intent, i.e. to develop a soft-real-time application, avoiding garbage collection as much as possible, a very special and rare situation in the Java world.
So the following answer does not match his problem. But as a casual reader migrating from C++ to Java might stumble over this question and answer, he/she might get some useful hints on typical Java programming style.
Although the syntax of Java and C++ have quite some similarities, because of the very different runtime environments, you should adopt a different coding style.
As a decades-long Java guy, I'd surely prefer the original method signature. As a caller of the D() method, why should I create the results data structure instead of getting it from the method I am calling? That reverses the natural flow of data.
I know, in good old C times when dynamic memory management meant lots of headache, it was very common to prepare the result array outside of the function and have the function only fill in the results, the way you wrote the second version. But forget about that with Java, and just let the garbage collector do its job (and it's very good at that job). Typically trying to "help" the GC results in code that's in fact less efficient and harder to read. And if you really want to stick to that style, there's no need to pass both the max rows number and the array, as the array itself knows its length (that's different from old-style C arrays), giving the max row number.
You assume
the second version should avoid creating and copying MyData's
That sounds like a misconception about Java's inner workings. Every time you execute a new MyData(...) expression, you create a new instance somewhere on the heap. Providing a MyData[] array doesn't avoid that. Translated to C terminology, the array just holds pointers to MyData objects, not the real objects. And Java instances are hardly ever copied (unless you explicitly call something like object.clone()). It's just the reference (= pointer) to the instance that gets copied when you assign something to a variable.
But even the first version is far from perfect, if I understand its purpose correctly. The D() method itself can determine when there's no more data available, so why should it return an array longer than necessary? With Java arrays that's a bit inconvenient, so typical Java code returns a List<MyData> in similar situations.
One more comment on the MyData() constructor and later "calculate or fill in MyData structure". I know that style exists (and is quite popular in the C family of languages), but it's not predominant in Java, and I especially dislike it. To me, it sounds like asking "Give me a car" and getting just a skeleton instead of a usable car. If I want it to have wheels, an engine and seats, I later have to supply them myself. If a usable car needs the selection of options, I want to supply them when ordering the car / calling the constructor, so that I can honestly call the result a car instead of a skeleton.
And finally a comment on the Java naming conventions: the vast majority of Java code follows the conventions, so your method names beginning with upper case look very strange to me.

Fastest way to utilize huge vector (or array?) of objects in C++ vs. Java

I'm writing some code for a computational biochemistry project, and I need to be able to have an array or vector with upwards of 10 million objects, and to run ~50-100 million monte carlo iterations where each iteration could modify an object from the list at random. I'm relatively new to C++, transitioning from Java (hoping among other things for more speed improvements).
My lab is in the process of ordering a computer with 128 GB RAM and 2 processors, but my current computer has 4GB RAM.The compiler I have at the moment is Visual Studio Express, though I've heard G++ is used by some of our collaborators.I'd be grateful for compiler recommendations if anyone has any, since I know some have run time performance differences.
My main problem is that I can't even get these declarations to reasonably compile:
#include <iostream>
#include <random>
#pragma pack(push, 16) //Mostly ignorant about what this does
using namespace std;
struct RNAObject {
public:
string sequence;
string seqComplement;
int bindingInx5Prime;
int bindingInx3Prime;
int length;
enum type {MONOMER, SINGLE_STRAND, DOUBLE_STRAND, HAIRPIN, RIBOZYME};
};
void main() {
const static int maxSize = 10000000;
//RNAObject RNASoup[maxSize]; -Does not compile, stack overflow
//RNAObject* RNASoup[maxSize]; -Does not compile, stack overflow
vector<RNAObject> RNASoup(maxsize); //Compiles, but extremely slow already
cout << "Hello World"; //Stopped the compile before this line could happen
}
However, in my Java setup on the same computer, the following lines compile immediately, with no difficulty at all:
int maxSize = 10000000
RNAObject RNASoup[] = new RNAObject[maxSize];
I have a long way to go, so any pertinent recommendations would be greatly appreciated.
Your two pieces of code (C++ and Java) are not equivalent.
Your C++ vector declaration creates a vector of maxSize objects, and assigns a newly instantiated object into each of the maxSize elements (hence the slow startup time).
Your Java code simply creates maxSize references to RNAObjects. The equivalent Java code to your C++ code would be:
int maxSize = 10000000
RNAObject RNASoup[] = new RNAObject[maxSize];
for (int i = 0; i < maxSize; i++)
RNASoup[i] = new RNAObject();
There are two places from which memory can be allocated: heap and stack. Stack is rather limited and is used for small objects, however it is much faster. Any declaration of the form:
Sometype someVariable;
Allocates a variable on the stack.
Any declaration involving new uses memory from the heap, which is almost always limited only by your computer's operative memory amount. Next declaration allocates a pointer to Sometype on the stack, and an instance of Sometype at the heap:
Sometype* someVariable = new Sometype();
Now regarding your code:
1). RNAObject RNASoup[maxSize]; - creates one dimensional array of RNAObjects on the stack.
2). RNAObject* RNASoup[maxSize]; - creates one dimensional array of RNAObject pointers on the stack.
3). vector<RNAObject> RNASoup(maxsize); - creates a vector on the stack, nevertheless vector stores its data at the heap, so it works. However vector is not very suitable for your use-case: it was designed for storing data, which length changes dynamically, and this feature drains a lot of performance.
So what you really want is:
RNAObject* RNASoup = new RNAObject[maxSize];
Which creates a pointer to the array on the stack, and allocates that array at the heap.
Also, from you question it is totally obvious that you don't understand even the basics of C++. You should learn the language before writing in it, otherwise you will be in a huge trouble very soon.
your used string and vector in your code, so you need
#include <string>
and
#include <vector>
Also, because iostream, string and vector are all in std namespace, so you need to explicitly using this namespace by adding
using namespace std;
or use fully qualified names like
std::cout
std::vector
etc. for your code to work.

Is there a way to have the equivalent of a struct in Java 1.4?

Using the common example of a Point (x, y) object, is there a way to have it as a struct in Java 1.4? The advantage would be that there would not be a separate memory allocation for the Point object because the struct would be part of the containing object. But it would still have member functions to access it.
I'm 98% certain the answer is no but hope springs eternal...
what/why:
In our code we have 100,000+ objects (about 12 - 14% of the total memory footprint) that is an int and a boolean. If that was a C# struct inside the object, it would reduce the number of objects. And... we are looking at making it just an int where 0x40000000 is the boolean value. But handling that is a lot easier if we have member methods for that int and it's treated as a struct.
There is no struct equivalent on Java now, although I believe that they have been hinted for future versions. Still have a look at the flyweight pattern, might be what you are looking for http://en.wikipedia.org/wiki/Flyweight_pattern
No, you have to use Objects for general "structs".
However for simple data structures like pairs of ints, you can use a bit of trickery in order to save memory and increase speed.
int a = 9;
int b = 10;
long pair = (a << 32)|b;
This packs the 32 bits of a and b into a long. Here's how you extract them:
a = (int)(pair >> 32);
b = (int)pair;
An addition to tskuzzy's answer: another possibility would be to lift the int x and int y fields from the Point class into any classes that need to store point values.
Edit in response to comments:
One thing you could do is to have each class that needs to store a single point value extend a Point class. There would be no logical is-a relationship, but it gives you access to Point objects through a single interface. This wouldn't work (I don't think) for any classes that need to store multiple point values, though.

Java - Efficient way to access an array

it's been some time since I last coded in Java, but I need a little hint here.
We have a simple function - note that this is C:
void update(double *source, double *target, int n) {
for(int i = 0; i < n; ++i)
target[i] = source[i] * i; // well, actually a bit more complicated, just some kind of calculation
}
So, now I need to recode this function in Java - efficiently. My problems are:
Java has of course no pointers, so how can I pass the arrays efficiently without having large amounts of memory copy operations due to call by value
Which data structure is the best to store the arrays
Note that source and target are large arrays, storing up to 1 million elements
In Java it's almost the same thing:
static void update(double[] source, double[] target, int n)
{
for (int i = 0; i < n; i++)
target[i] = source[i] * i;
}
You don't copy any memory. When you pass an array into this function, it's passing a reference to an array by value.
In general, Java passes function arguments by value. But in the case of arrays and user defined classes, the objects you're dealing with are always reference types. So function calls on classes and arrays are always passing the class/array reference by value.
So if you have a class that looks like:
class Foo
{
int[] A; // For arguments say let's say this contains 1 million items always
}
and you have a function that you can call on it:
static void Bar(Foo f)
{
....
}
It only passes the reference to the Foo, it doesn't make a copy of the data at all.
Arrays are passed by reference, (the value of the reference is passed). So there won't be any new copy of array.
Code will be quite similar:
void update(double source[], double target[], int n)
{
for (int i = 0; i < n; i++)
target[i] = source[i] * i;
}
What do you mean by 'data structure for array'? Array itself is a data structure. You anyways have to access each element for the type of operation you are trying to do. So array itself is a good data structure I guess. You may wanna look at ArrayList.
As some others have already pointed out by-ref / by-value is a C/C++ thing and not applicable to Java.
Now unless you're doing some real native coding passing these arrays C/C++ to / fro Java:
Given that in C code array is passed as pointer (void update(double *source, double *target, int n)) I assume it's size is dynamic, if so your signature in Java should be void update(List<Double> source, List<Double> target, int n). Let the caller decide if it's an ArrayList or Vector or LinkedList or ...
But if you're into some JNI (passing these arrays C/C++ to / fro Java) then perhaps we need to consider other aspects.
The Java Spec says that everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java.
But, don't be fooled by this, the internal working is pretty complex, and you can actually manipulate the arrays the way you want.
Verbatim from Oracle's java Tutorials:
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.
However, the values of the object's fields can be changed in the
method, if they have the proper access level.
Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail.
the code to use is similar and straightforward:
void update(double source[], double target[], int n)
{
for (int i = 0; i < n; i++)
target[i] = source[i] * i;
}
For a better understanding of what I mentioned, have a look at this question: Is Java "pass-by-reference" or "pass-by-value"?
As to your question of data structures, use an Array. Looking at your snippet, it is clear that you need random access, so just stick to good ol' arrays..
Java uses references for arrays (and other objects). The value of the reference, not the array itself, is passed in method calls, with cost similar to C pointers. If you don't need to expand them dynamically, simple arrays are the fastest data structure to use.
Otherwise, consider ArrayList<Double>. But these are much more expensive, in both speed and size, because each double is "boxed" in a Double object.
A third alternative is to use a relevant resizable list class from a library with high-performance primitive collections, like Trove's TDoubleArrayList.
A question you didn't ask, is whether Java will use any relevant SIMD features of your processor for a simple loop like this. And I'm glad you didn't, because I don't know. But I'm fairly confident that if it is smart enough to use them, it will only be for simple arrays.
Java uses call-by-object semantic, so there is no copying.

Categories

Resources