Show Lecture.Traps as a slide show.
CS253: C++ traps for the unwary Java programmer
This is not a list of all Java/C++ differences. Instead, it is a list of differences that are likely to cause problems for a programmer who knows Java but is learning C++.
If you ask, “Why doesn’t C++ do such-and-such a thing like Java?”, then you’re asking the wrong question.
In Java, everything’s a method, because everything’s in a class.
C++ has methods inside of classes. However, C++ also has
functions outside of classes, like main()
.
public static void main(String[] args)
int main()
int main(int argc, char *argv[])
In C++, main
returns an int indicating success/failure.
Zero indicates success, positive numbers indicate failure.
It’s not a boolean success indicator. It’s an integer code.
In C++, main
uses an array of old-style C char *
strings,
for compatibility with C.
boolean b = true; if (b) System.out.println("true in Java");
true in Java
bool b = true; if (b) cout << "true in C++\n";
true in C++
Neither is “Boole”, which was how the guy spelled his name.
In Java, true
is true.
In C++, any non-zero value is true.
if (42) System.out.println("true in Java");
Code.java:1: error: incompatible types: int cannot be converted to boolean class Code { public static void main(String[] args) { if (42) ^ 1 error
if (true && 42 && 3.14159 && 'x' && "hello") cout << "true in C++\n";
true in C++
char
, byte
char
byte
(C++17)
C++’s char
type is the closest approximation to Java’s byte
.
Java’s char
can hold Unicode characters.
C++’s char
has an implementation-defined size, but it’s typically
a single byte.
final
final
, const
, constexpr
In Java, final
indicates a non-overrideable method,
or a constant value.
In C++, final
indicates a non-overridable method.
const
indicates a method that doesn’t alter object state,
or a value that you can’t change.
constexpr
indicates a compile-time constant.
int[] a = new int[100];
int a[100];
In C++, arrays are not objects. Hence, they have no methods.
Hence, you can’t ask an array how long it is. Use a vector
or std::array
instead, if you want that.
The simple term “array” is, alas, ambiguous. We will use the
phrases “C-style array” or std::array
to resolve this.
String
string
In Java, classes start with a capital letter. That’s not always so in C++.
"what type am I?"
"this is a C-style string"
char name[] = "a classic C string; no methods here!";
string s = "a std::string, initialized with a C string";
"foobar"
, is not an object
of type std::string
. It is an anonymous array of constant
characters, or a const char []
, which is pretty much the same
as const char *
.
String s = new String;
string s;
int
, double
) are always on the stack.
new
and delete
.
String s = "abcdefg"; System.out.println(s.charAt(3));
d
string s = "hijklmn"; cout << s[3] << '\n'; cout << s.at(4) << '\n';
k l
string
class has an .at()
method, but, why?
int n=0; System.out.println(++n + ++n);
3
int n=0; cout << ++n + ++n << '\n';
c.cc:2: warning: operation on 'n' may be undefined 4
The Java example yields 3
, because the order of operations
is defined by the language.
The C++ example invokes undefined behavior. The compiler is free
to do those operations (++
, ++
, +
) in whatever order
it considers to be best. The compiler is not required to tell
you if you broke the rules.
System.out.println("foobar"+3);
foobar3
cout << "foobar"+3 << '\n';
bar
In Java, +
is overloaded to handle arguments of String
and int
,
and so yields "foobar3"
.
C++ performs address arithmetic in this case, and so yields "bar"
.
int[] reed = {1,2,3}, sue = reed; // reed & sue share data reed[0] = 4; System.out.println(reed[0] + " " + sue[0]);
4 4
vector<int> ben = {1,2,3}, johnny = ben; // johnny is a copy of ben ben[0] = 4; cout << ben[0] << ' ' << johnny[0] << '\n';
4 1
This C++ code uses no pointers or references.
obj1 = obj2;
obj1 = obj2;
In Java, this copies a reference. No new object is created, no real data is copied.
In C++, the copy ctor of the class is called. This typically copies the data in the object.
String s = "foobar"; System.out.println(s.length());
6
string a = "xyzzy"; string *b = new string("alakazam"); cout << a.length() << ' ' << b->length() << '\n'; cout << a.size() << ' ' << b->size() << '\n';
5 8 5 8
alpha.beta()
, since alpha
can only be a reference.
alpha.beta()
or alpha->beta()
,
because alpha
might be an object, a reference to an object,
or a pointer to an object.
delete
and delete[]
In C++, your options are (hardest to easiest):
new
/ new[]
,
deallocate with delete
/ delete[]
.
vector
or set
which do the
memory allocation/deallocation for you.
int[] a = {11,22,33}; System.out.println(a[-12]);
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -12 at Code.main(Code.java:2)
int a[] = {11,22,33}; cout << a[-12] << endl; cout << a[-12000000] << endl;
0 SIGSEGV: Segmentation fault
Java throws an exception.
C++ assumes that you know what you’re doing.
null
nullptr
or NULL
or 0
In Java, null
is the reference to nothing.
In C++, a pointer to nothing useful can be initialized
to nullptr
or NULL
or 0
.
nullptr
is best
NULL
is compatible with C
0
is just plain stupid