CS 1124 Object Oriented Programming
Java to C++
The purpose of this document is to help those with a background in Java, make the transition to programming in C++. It is specifically targetted at students taking CS1124 at Brooklyn Poly, who have either advanced placement or transfer credit from an introductory Java course.
Two things to note before we dive in:
- First, these languages are vey similar. Loops, if / else, and many other constructs are either exactly the same or very close.
- Both languages have their advantages. The goal here is not to argue in favor of one or the other, only to
observe critical differences that will impact the student.
A First Program
Let's start by looking at how the traditional "hello world" program might be written in Java and C++.
In Java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
In C++:
#include <iostream>
using namespace std;
int main() {
cout << "Hello world!\n";
}
So, how do these programs compare?
- In Java, we define a class. In C++, for such a simple program there is no need.
- In C++ we need the line "#include <iostream>". It tells the compiler where to find the libraires for I/O. In Java, you don't have to bother with that sort of thing. You will find yourself writing a lot of #include's.
- In C++ we need the line "using namespace std". This is similar in Java to an import. In Java you don't need an import here, because the class System is in the package java.lang, and that is automatically imported for you.
- Both languages use a function called main to start off the program!
- In Java main always takes an array of String. In C++, we can pass in a similar array, but we don't have to if we're not going to use it in our program. (In this course we never do pass anything to main.)
- In Java main returns void. In C++, it returns an int.
- You might notice that we aren't actually returning any int in the C++ version. In any other function, you would get a compilation error for not actually returning something when you say the function has a non-void return type. However, main is an exception. It is perfectly legal in main not to return anything. But the return type still has to be int.
- In Java main must be public. This is necessary because main belongs to the class HelloWorld, and we have to specify who is permitted to access the function. Since in C++ main does not belong to any class, there aren't any restrictions to who can call it.
- In Java main must be static. Again, this is necessary because main belongs to a class. If it wasn't static, then you would need an instance of HelloWorld in order to call main, but who would create the instance before you ran the program??? So, it has to be static in Java. In C++, there is very little use for static methods. They do exist and they mean the same as in Java, they just aren't needed.
- In Java, simple output to the "screen" is done using the object called System.out, using methods such as println, which adds a newline character at the end of the string. In C++, we also use an object. It is named cout. Simple output is generally done using the operator <<.
The object on the left side is the object representing an output stream,
while the thing on the right is what you want to print.
- Note, you may recognize this operator as the arithmetic left-shift operator from Java. Yes, the << operator actually also does that in C++, if the values on both sides are integers. However, C++ can use operators for more than one thing. Many C++ programmers think of << as the "output operator".
- One other point isn't obvious. In Java, the source file had to be named HelloWord.java. In C++, we are free to name it whatever we want. I did choose to name it HelloWorld.cpp. "HelloWorld" seemed like a reasonable choice and we use "cpp" for the file extension for C++ files.
Basic Types
Java and C++ have similar built-in types.
Integers
- Types of integers
- Java has several types of integers: byte, char, short, int and long.
- C++ has char, int and long.
- C++ can also specify that an integer will be unsigned. Java's only unsigned type is char and normally that is not used for arithmetic.
- An unsigned int would be defined as:
unsigned int x;
or just:
unsigned x;
- Sizes
- Java specifies the size of each of its types. E.g., an int is always 32 bits.
- C++ doesn't give any guarantees other than the size of an int is at least as large as a char and the size of long is at least as large as an int. In fact you will find that (annoyingly) on many platforms both ints and longs are 32 bits!
Floating Point
Boolean
- In Java, the type is
boolean
, whereas is C++ it is bool
.
- In C++, numbers can be implicitly coerced to bool. The number zero is considered false and anything else it considered true.
Reading a File
There are a number of ways to read files. The easiest in many cases is to use the class Scanner, which allows you to directly read in the various built-in types, along with lines and whitespace-delimited "words". Here is a simple program to read in a file of integers, displaying their sum and average.
In Java:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ReadFile {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(new File("nums.txt"));
int tot = 0, n = 0;
while (scan.hasNextInt()) {
int num = scan.nextInt();
tot += num;
++n;
System.out.print(num + " ");
}
System.out.println("T\notal: " + tot + "; Avg = " + tot/n);
}
}
In C++, the code looks like:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream ifs("nums.txt");
int tot = 0, n = 0;
int num;
while (ifs >> num) {
tot += num;
++n;
cout << num << " ";
}
cout << "\nTotal: " << tot << "; Avg = " << tot/n << endl;
}
Before we compare the code, we should note that neither program properly handles the situation in which we fail to open the file nums.txt. You could say that Java does a better job here, as it will crash the program by throwing a FileNotFoundException.
Now onto the code comparison. I won't discuss things that were already covered in our early code comparison.
- Java has an import for each of the three classes File, FileNotFoundExceoption and Scanner. (Yes we could combine the first two, if we wanted. C++ has an include to say that we need the classes defined in the library fstream.
- Opening the file.
- Java creates a File object and a Scanner to open the file.
- C++ defines an ifstream object.
- This line will look somewhat strange to Java programmers. Yes, ifstream is a class and ifs is a variable of that type. In Java however, a variable that holds anything other than a built-in type is a reference and either has the value null or else is assigned an object that was created with the keyword new and located on the heap. C++ uses the heap also, along with the keyword new, but not here. In this case the ifstream object lives on the runtime stack (also known as the "call stack"), so we don't have to use new. This is an important point. C++ can create objects on the stack. We will see later how C++ manages the heap.
- Allocating objects on the heap will be covered in CS1124 after a few weeks. It is not covered in the first semester, so none of our early examples will make use of the keyword new or the heap.
- I have omitted code that would check whether the file was successfully opened. Actually, in Java we were forced to recognize this possibility and I handled it with the exception specification: throws FileNotFoundException. If the file fails to open, the Java program will crash, throwing that exception. (This is good.) The C++ program will just continue along. In both languages we should have added code to properly handle this situation and print a useful error message.
- Both programs define and intialize the ints tot and n to hold the total of all the numbers to be read and the count of how many there are.
- C++ defines the variable num to hold a single number before the loop, whereas we place that definition inside the loop in Java. We will see why C++ does this in the next item.
- Loop Control
- Java's loop control, asks the Scanner if there are any more ints to be read.
- C++ is doing the same thing, but is also reading the next int at the same time. Note that C++ is using the operator >> to read from the file stream object into the int variable. C++ knows that it is looking for an int because of the type of the variable on the right-hand side, num. Like Java, C++ will skip over any whitespace before it comes to the int, but if there were any non-digit characters other than whitespace before the int, then the read would fail. Unlike Java, no exception would be thrown. We will talk later on about how a C++ programmer could detect such a failure.
- If there was no int to be read, both languages would end their while loops. If there is, C++ also reads the int, whereas Java will wait till it is inside the loop to do so.
- Inside the loop, Java then defines num and assigns it the next int in the file. C++ has already done this, as discussed above.
- Both languages add the new number onto the total and incerment the count.
- Both languages print out the number read followed by a space. These two different lines show an interesting difference in the approach taken to simple output.
- Java uses string concatenation, implicitly converting the int num to a string and concatenating it with " " to form a new string that is then printed.
- C++ chains the output operator, resulting in:
cout << num << " ".
- First the expression cout << num is evaluated. This will print out the int num.
- That expression also has a value. Its value is output stream object on the left-hand side, cout.
- Using the value, cout, we then evaluate the expression: cout << " ". That prints out the string consisting of just a space character.
- So, what's the difference? Java tends to build up the string to print, while C++ tends to print each piece as it goes. This will show up again later. In particular, C++ does not make use of a method toString() as Java does. Java's toString is normally used to create a printable version of an object. C++ takes the approach that if we want to print an object, then we should just write a function to do precisely that. Again, we'll see this later.
- Finally both languages print the total and that average. Oh, to generate a newline at the end for C++, I output the object endl. It's purpose is simply to generate a newline. I could just as well have printed the string "\n". Java's println, of course, generates its own newline.
Arrays
Arrays in Java and C++ have a number of similarities and also a number of differences.
Note that in both languages, it is common to instead use a more powerful and flexible class for holding groups of things. In Java that would normally be the ArrayList, while in C++ it is the vector. However, in simple cases arrays are still used in both languages, so they are worth comparing.
To highlight the basic use of arrays, let's take our earlier program that read a file of integers, summing them and computing their average. Here we will read the numbers into an array.
In Java:
int n = 0;
int[] arr = new int[10];
while (scan.hasNextInt()) {
int num = scan.nextInt();
arr[n++]= num;
}
System.out.println("T\notal: " + tot + "; Avg = " + tot/n);
In C++, the code looks like:
int tot = 0, n = 0;
int num;
while (ifs >> num) {
arr[n++]= num;
}
cout << "\nTotal: " << tot << "; Avg = " << tot/n << endl;
The above code looks very similar. First let's examine it. Then we will explore further some of the major differences between Java's arrays and those of C++.
General Issues
- Both
languages "derive" from C.
- Basic
built-in types, loops, conditionals, etc. generally work the same way.
- Java
is a "pure" OOP language, requiring that every function be in a class.
- C++
is a "hybrid" language. C++ is much
closer to C than Java is. Functions
can exist without being in classes!
- C++
tries not to force unneeded runtime
or space overhead onto programmers for features they don't use. This has a wide impact. Some things that Java programmers take
for granted require extra programming in C++.
- C++
does not have garbage collection, but objects created "locally" or "on
the stack" will be reclaimed when the enclosing block (e.g., a function)
ends.
- C++ basic
program structure: int main() {}
- Forward
declarations / prototype. The
function declaration/definition must be seen before a function is called.
- Libraries:
iostream, string, vector, cmath, ???
- Built-in
types
- char, int and long
- signed
vs. unsigned (not in Java).
- float and double
- bool (in Java: boolean)
- const (like a final field in Java)
- sizes/limits. Java specifies the sizes and ranges of
its basic types. C++ only gives
relative sizes (e.g. an int is at least as large as a short).
- references
- arrays. Much more "primitive" in C++ than in Java.
- Don't
know their own size. When you
pass a C++ array to a function you normally pass its size also.
- Declared
size must be a constant, not a variable. We have to know the size of the array at compile time. (In Java the size may be specified at
runtime.)
- In
Java, arrays are objects, so array variables are references. An array variable can refer to
different arrays at different times. In C++, an array variable refers to a specific array and cannot
change. [This limitation is
removed when we cover pointers.]
- Operators
(not a complete list)
- arithmetic: +, -, *, /, %
- logical: &&, ||, !
- <<, >> [No >>> in C++.] Used for both shifting bits and also
for I/O.
- =, +=, -=, /=, *=, .
- ++, --. Both pre and post.
- ? :
- Bitwise: &, |, ^, ~. In Java & and | can also be
logical, but without short-circuiting.
- Order
of evaluation. Java guarantees left-to-right. C++ makes no guarantees (except in the short-circuiting operators
&& and ||.
- Boolean
expressions
- Type: boolean in Java, bool in C++.
- In
Java the "condition" in a conditional or looping construct, such as:
if (condition) statement;
has to be of type boolean, otherwise it won't
compile.
- In
C++, many things can be automatically converted to bool. All built-in / primitive types are
treated as false if they
have the value zero and true otherwise. Pointers are similarly false if they are NULL and true otherwise.
- In
C++, it is legal (and common) to have:
if
(x = y) statement;
Since Java requires the condition to be of type boolean, the expression x = y would only compile if x and y are boolean
otherwise it is a compilation error.
- Java's import
- works
with packages. No exact match in C++. Does not load any files.
- tells
where a class is located in the file system. C++ uses #include.
- protects
against name collisions. C++ uses
namespaces.
- interacts
with access protection. (default
and protected access)
- Defining
types: struct / class
- struct Cat {}; //NB:
Semi-colon required in C++!
Cat c; // Creates a Cat, not just a variable
// that can refer to a Cat.
- C++
types (also functions) must be declared before they are used. This is the purpose of the #include construct.
- C++
only allows initialization of member variables (aka instance variables or
fields) in the constructor. It is an error to try to initialize
a member variable where it is defined in the class definition.
- Java:
members (fields and methods) are declared
public/private/protected/default individually.
- In
Java objects (anything other than built-in types) are all placed on the "heap" (JPL
1.7.1). Variables of a defined
class are called "reference variables" and are initialized to NULL by
default. "Primitive types" are
presumably placed on the call stack (though I do not find this in JPL).
- Primitive
types ("numeric fields") are initialized to 0.
- C++
Access:
- Access
specifiers are not covered in 1114, but would be in a Java AP class.
- Access
specifiers apply to sections of code, not single definitions.
- Classes
(other than nested classes) cannot be marked with an access modifier.
- structs use
public by default.
- protected in Java includes
package access. In C++ protected
simply extends private to
include derived classes.
- C++
classes use private by
default. (not in CS1114)
- Nothing
corresponds to Java's "default" access, which works at the package
level.
- protected: Allows access by the
class and subclasses. Unlike Java
which also allows access by
classes within the same package.
- Object class. In Java Object is the ultimate ancestor of every class. In C++ there isn't any such thing. C++ tends to use templates, instead. (Covered in the second half of the
semester), which helps to avoid much of the casting required in Java. C++ containers are type specific,
unlike Java's "collections".
- Initialization
in C++ is somewhat different than in Java. (not in CS1114)
- In
both, constructors the name of the class and have no return type.
- C++
does not have "initialization blocks" nor can instance variables be
initialized where they are declared.
- "Initialization"
in C++ constructors requires use of the initialization list. Assignment inside the constructor body
does not qualify as initialization - it could not be used, for example,
for a const/final member.
- Overloaded
constructors cannot make use of this() to invoke another version. However default parameter values can often be used to accomplish
a similar goal.
- What
Java calls the "no-arg constructor", C++ calls the default
constructor. Java's "default
constructor" is C++'s "system-provided default constructor".
- this: in Java is a reference and
in C++ is a pointer. (not in
CS1114)
- Garbage
collection. In Java all objects are
collected automatically. In C++
objects which are created with "new" must
be freed with "delete", otherwise there will be a memory leak. Local objects are freed automatically at
the end of the enclosing block. (Ok, C++ will eventually clean up the garbage, but not till the program
ends.)
- Terminology: [JPL 1.8] invoke a method. Given
the function call: someObject.someMethod(),
then someObject is referred to as the target object. Within someMethod, it
would be referred to as the current or receiver object.
- References:
The word "reference" means very different
things in Java and C++.
- In
Java all variables that "hold" defined types are "references".
- In
C++ a reference is an "alias" and must be bound when it is defined.
Cat& c; // Illegal. Must say what c is a
reference to.
- Named
constants (const vs. final)
- In
Java, the keyword is final,
while in C++ it is const.
- NB:
C++ does not have Java's concept of a final method or of a final class.
- Java
has no way to state that an object will not be changed through a
reference. Java's final when used with a reference
variable is most similar in nature to C++'s reference variables. In both the reference can not change,
but the state of the object referred to can.
- One
key difference in using constants is for the size of an array inside a struct/class. In Java one would say:
class SomeClass
{
private static final int SIZE =
17;
private int[] array = new
int[SIZE];
}
In C++, if we want the array to be local, instead of on the heap we
cannot initialize a constant field until we execute the constructor. Instead of the corresponding:
class SomeClass
{
private:
static const int SIZE = 17; // WRONG.
//
Can't inititalize here.
int array[SIZE]; // WRONG. SIZE was never initialized.
};
Instead we need to write:
class SomeClass
{
private:
enum {SIZE = 17};
int array[SIZE];
};
- I/O
- istream and ostream
- #include <iostream>
using namespace std;
- cout, cin, cerr
- ifstream and ofstream
- open
method
- ifstream ifs;
ifs.open("inputFile.txt");
- or:
ifstream ifs("inputFile.txt");
- Testing
if open was successful
if (!ifs) { . }
- input:
>>
- skipping
whitespace
- looping
through a file.
while (ifs >> x) { . }
- output:
<<
- Provided
classes: string and vector.
- vector is like ArrayList.
- But
like arrays usually uses [] to access members. Can also use the method "at", if bounds-checking is
desired.
- If
a and b are declared to be vectors (of the same type), then
a = b in C++ creates a new vector to be a copy of b.
In Java, a and b would refer to the same ArrayList.
- In
Java, you can only use == to test if two variables refer to the exact same
object. In C++, by default the ==
operator for objects checks each field for equality. In vector and string, for example, it works
like the equals method in Java, comparing for equality of the respective
elements of the vector (or string).
- Functions
- Signature
- Prototype
- Parameter
passing
- By-value
(the only form in Java)
- By-reference
- Const
reference
- Return
types. By-value, by-reference,
by-const-reference.
- Passing
arrays
- Inheritance
(not in CS1114)
- In
Java polymorphism is used by default, except for private methods. (Note that In Java, private methods are not called polymorphically.)
- In
Java, methods in a derived class can overload without overriding. In C++, if a method in a derived class
has the same name as a method in the base class, then all methods with that name from
the base class are overridden.
- Java's
keyword super does not
exist in C++. Base class
constructor is called explicitly in the initialization list.
- In
Java, method access can not be narrowed if overridden in a derived class. C++ does not have such a restriction.
- protected in Java is much less
protective than in C++, since in Java protected allows package-wide access while in C++ access is granted only to the
class and its descendants.
- Static
methods in Java are not inherited. I don't believe that C++ has such a restriction.
- Development
environment. At Poly we use
Microsoft .Net.
- Creating
a Windows Console project in .Net
- Adding/removing
files from a project.
- Indentation.
- Building
a project. Running.
- The
debugger basics.
Home
Maintained by John Sterling
(jsterling@poly.edu). Last updated
January 23, 2011