Sei sulla pagina 1di 29

www.horstmann.com/ccj2/ccjapp3.

html

Moving from Java to C++


This appendix explains how to transfer your Java programming skills to a substantial
subset of C++. This is necessary for students who take their first programming course in
Java and the second course in C++. Naturally, it would be easiest if the second course
were also offered in Java, but learning to move from one language to another is a fact of
life for today's software professionals. Fortunately, C++ has many features in common
with Java, and it is easy for a Java programmer to gain a working knowledge of C++.
Nevertheless, C++ is a much more complex language than Java. This appendix does not
attempt to cover all features of C++. But if you master all of the constructs described in
this appendix, you will be able to use C++ effectively.

We only cover the differences between Java and C++. In particular, control flow (if,
while, for) is essentially identical in C++ and Java, and it is not covered here.

This appendix describes ANSI C++. Some older C++ compilers lack essential features
described here. To use those compilers, you will need to learn more about the parts of
C++ that were inherited from C. That is beyond the scope of this discussion.

A3.1. Data Types and Variables


The data types in C++ are similar to those in Java. Like Java, C++ has int and double
types. However, the range of the numeric types such as int is machine-dependent. On
16-bit systems such as PCs running DOS or Windows 3.x, int are 2-byte quantities with
a much more limited range than the 4-byte Java int type. On those machines, you need
to switch to long whenever the int range is not sufficient.

C++ has short and unsigned types that can store numbers more efficiently. It is best to
avoid these types unless the added efficiency is crucial.

The Boolean type is called bool in C++.

The C++ string type is called string. It is quite similar to the Java String type.
However, pay attention to these differences:

1. C++ strings store ASCII characters, not Unicode characters

2. C++ strings can be modified, whereas Java strings are immutable.

3. The substring operation in C++ is called substr. The command s.substr(i, n)


extracts a substring of length n starting at position i.

4. You can only concatenate strings with other strings, not with arbitrary objects.
5. To compare strings, use the relational operators == != < <= > >=. The last four
operators perform lexicographic comparison. This is actually more convenient than the
use of equals and compareTo in Java.

A3.2. Variables and Constants


In C++, local variables are defined just as in Java.

int n = 5;

There is, however, a major difference between C++ and Java. The C++ compiler does not
check whether all local variables are initalized before they are read. It is quite easy to
forget initializing a variable in C++. The value of the variable is then the random bit
pattern that happened to be in the memory location that the local variable occupies. This
is clearly a fertile source of programming errors.

As in Java, classes can have data fields and static variables. Furthermore, variables can be
declared outside functions and classes. These so-called global variables can be accessed
from any function in a program. That makes them difficult to manage. C++ programs
should avoid global variables.

In C++, constants can be declared anywhere. (Recall that in Java, they had to be static
data of a class.) C++ uses the const keyword instead of final.

const int DAYS_PER_YEAR = 365;

A3.3. Classes
The definition of classes in C++ is somewhat different than in Java. Here is an example: a
C++ version of the Point class:

class Point /* C++ */

public:

Point();

Point(double xval, double yval);

void move(double dx, double dy);

double getX() const;

double getY() const;


private:

double x;

double y;

};

There are several essential differences.

1. In C++, there are public and private sections, started by the keywords public and
private. In Java, each individual item must be tagged with public or private.

2. The class definition only contains the declarations of the methods. The actual
implementations are listed separately.

3. Accessor methods are tagged with the keyword const

4. There is a semicolon at the end of the class

The implementation of methods follows the class definition. Because the methods are
defined outside the classes, each method name is prefixed by the class name. The ::
operator separates class and method name. Accessor methods that do not modify the
implicit parameter are tagged as const.

Point::Point() { x = 0; y = 0; }

void Point::move(double dx, double dy)

{ x = x + dx;

y = y + dy;

double Point::getX() const

{ return x;

A3.4. Objects
The major difference between Java and C++ is the behavior of object variables. In C++,
object variables hold values, not object references. Note that the new operator is never
used when constructing objects in C++. You simply supply the construction parameters
after the variable name.

Point p(1, 2); /* construct p */

If you do not supply construction parameters, then the object is constructed with the
default constructor.

Time now; /* construct now with Time::Time() */

This is very different from Java. In Java, this command would merely create an
uninitialized reference. In C++, it constructs an actual object.

When one object is assigned to another, a copy of the actual values is made. In Java,
copying an object variable merely establishes a second reference to the object. Copying a
C++ object is just like calling clone in Java. Modifying the copy does not change the
original.

Point q = p; /* copies p into q */

q.move(1, 1); /* moves q but not p */

In most cases, the fact that objects behave like values is very convenient. There are,
however, a number of situations where this behavior is undesirable.

1. When modifying an object in a function, you must remember to use call by reference
(see below)

2. Two object variables cannot jointly access one object. If you need this effect in C++,
then you need to use pointers (see below)

3. An object variable can only hold values of a particular type. If you want a variable to
hold objects from different subclasses, you need to use pointers

4. If you want a variable point to either null or to an actual object, then you need to use
pointers in C++

A3.5. Functions
In Java, every function must be an instance method or a static function of a class. C++
supports instance methods and static functions of classes, but it also permits functions
that are not a part of any class. Such functions are called global functions.

In particular, every C++ function starts with the global function main.
int main()

{ . . .

There is a second version of main that you can use to capture command-line arguments,
but it requires knowledge of C-style arrays and strings, and we will not cover it here.

By convention, the return value of main is zero if the program completed succesfully, a
non-zero integer otherwise.

As in Java, function arguments are passed by value. In Java, functions were nevertheless
able to modify objects. However, since C++ object values are not references to actual
objects, a function receives a copy of the actual argument and hence can never modify the
original.

Therefore, C++ has two parameter passing mechanisms, call by value (as in Java) and
call by reference. When a parameter is passed by reference, the function can modify the
original. Call by reference is indcated by an & behind the parameter type.

void raiseSalary(Employee& e, double by)

{ . . .

Here is a typical function that takes advantage of call by reference. Note that it would be
impossible to write such a function in Java.

void swap(int& a, int& b)

{ int temp = a;

a = b;

b = temp;

If this function is called as swap(x, y), then the reference parameters a and b refer to the
locations of the arguments x and y, not the values of these arguments. Hence the function
can actually swap the contents of these variables.

In C++, you always use call by reference when a function needs to modify a parameter.

A3.6. Vectors
The C++ vector construct combines the best features of arrays and vectors in Java. A C++
vector has convenient element access, and it can grow dynamically. If T is any type, then
vector<T> is a dynamic array of elements of type T. The instruction

vector<int> a;

makes an initially empty vector. The command

vector<int> a(100);

makes a vector that has initially 100 elements. You can add more elements with the
push_back method:

a.push_back(n);

The call a.pop_back() removes the last element from a. Use the size method to find the
current number of elements in a.

You access the elements with the familiar [] operator.

for (i = 0; i < a.size(); i++)

sum = sum + a[i];

As in Java, array indexes must be between 0 and a.size() - 1. However, unlike Java,
there is no runtime check for legal array indexes. Accessing an illegal index can cause
very serious errors.

Just like all other C++ objects, vectors are values. If you assign one vector to another, all
elements are copied.

vector<int> b = a; /* all elements are copied */

Contrast that with the situation in Java. In Java, an array variable is a reference to the
array. Making a copy of the variable just yields a second reference to the same array.

For that reason, C++ functions that modify vectors must use reference parameters.

void sort(vector<int>& a)

{ . . .

A3.7. Input and Output


In C++, the standard input and output stream are represented by the cin and cout
objects. You use the << operator to write output.

cout << "Hello, World!";

You can print multiple items as well.

cout << "The answer is " << x << "\n";

To read a number or a word from input, use the >> operator.

double x;

cout << "Please enter x: ";

cin >> x;

string fname;

cout << "Please enter your first name: ";

cin >> fname;

The getline method reads an entire line of input.

string inputLine;

getline(cin, inputLine);

If the end of input has been reached, or if a number could not be read correctly, the
stream is set to a failed state. You can test for that with the fail method.

int n;

cin >> n;

if (cin.fail()) cout << "Bad input";

Once the stream state has failed, you cannot easily reset it. If your program needs to
handle bad input, you should use getline and then manually process the input.

A3.8. Pointers
In C++, object variables hold object values. This is different from Java, where an object
variable only is a reference to an object value that is stored elsewhere. There are
circumstances where the same arrangement is required in C++. In C++, a variable that
can refer to an object is called a pointer. If T is any type, then T* is a pointer to an object
of type T.

Just as in Java, a pointer variable can be initialized with NULL, with another pointer
variable, or with a call to new.

Employee* p = NULL;

Employee* q = new Employee("Hacker, Harry", 35000);

Employee* r = q;

Actually, there is a fourth possibility. Pointers can be initialized with the address of
another object, by using the & operator.

Employee boss("Morris, Melinda", 83000);

Employee* s = &boss;

This is usually not a good idea. As a rule of thumb, C++ pointers should only refer to
objects allocated wth new.

So far, C++ pointers look very much like Java object variables. There is, however, an
essential syntactical difference. You must apply the * operator to access the object to
which a pointer points. If p is a pointer to an Employee object, then *p refers to that
object.

Employee* p = . . .;

Employee boss = *p;

You also need to refer to *p when you want to execute a method or access a data field.

(*p).setSalary(91000);

The parentheses are necessary because the . operator has a higher precedence than the *
operator. The designers of C found this sufficiently ugly that they provided an alternate
-> operator to combine the * and . operators. The expression

p->setSalary(91000);

invokes the setSalary method on the object *p. You can simply remember to use the .
operator for objects, the -> operator for pointers.

If you do not initialize a pointer, or if the pointer is NULL or refers to an object that no
longer exists, then it is an error to apply the * or -> operator. Unfortunately, the C++
runtime system does not check against these errors. If you make such a mistake, your
program can die a horrible death or act flaky.

In Java, these errors are not possible. You cannot have an uninitialized reference. All
objects are kept alive as long as there is a reference to it. Hence you cannot have a
reference to a deleted object. The runtime system checks for null references and throws a
null pointer exception if a null pointer is accessed.

There is another significant difference between C++ and Java. Java has a garbage
collector that automatically reclaims all objects that are no longer needed. In C++, it is
the responsibility of the programmer to manage memory.

Object variables are automatically reclaimed when they go out of scope. However,
objects created with new must be reclaimed manually with the delete operator.

Employee* p = new Employee("Hacker, Harry", 38000);

. . .

delete p; /* no longer need this object */

If you forget to delete an object, then you can eventually exhaust all memory. This is
called a memory leak. More importantly, if you delete an object and then continue to use
it, you can overwrite data that no longer belongs to you. If you overwrite any of the data
fields that are used to manage the recycled storage, the allocation mechanism can
malfunction and cause subtle errors that are very difficult to diagnose and fix. For this
reason, it is best if you minimize the use of pointers in C++.

A3.9. Inheritance
The basic syntax for inheritance is similar in C++ and Java. In C++, you use : public
instead of extends to denote inheritance. (C++ also supports a concept called private
inheritance, but it is not very useful.)

By default, functions are not dynamically bound in C++. If you want which dynamic
binding for a particular function, you must declare it as virtual.

class Manager : public Employee

public:

Manager(string name, double salary, string dept);

virtualvoid print() const;


private:

string department;

};

As in Java, there is special syntax for a constructor to invoke the constructor of the
superclass. Java uses the keyword super. In C++, you must call the superclass
constructor outside the body of the subclass constructor. Here is an example.

Manager::Manager(string name, double salary, string dept)

: Employee(name, salary) /* call superclass constructor */

{ department = dept;

Java also uses the super keyword when a subclass method calls the superclass method.
In C++, you use the name of the superclass and the ::operator instead.

void Manager::print() const

{ Employee::print(); /* call superclass method */

cout << department << "\n";

A C++ object variable holds objects of a specific type. To exploit polymorphism in C++,
you need pointers. A T* pointer can point to objects of type T or any subclass.of T.

Employee* e = new Manager("Morris, Melinda", 83000, "Finance");

You can collect multiple objects of a mixture of super- and subclasses in a vector of
pointers, and then apply a dynamically bound function.

vector<Employee*> staff;

. . .

for (i = 0; i < staff.size(); i++)

staff[i]->print();
www.dickbaldwin.com/java/Java008.htm

Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us,


http://www2.austin.cc.tx.us/baldwin/

Similarities and Differences between Java and C++


Java Programming, Lecture Notes # 8, Originally published in 1997. Revised 10/03/99.

Preface
Introduction
An Initial Word about Java and C++
Similarities and Differences

Preface
By the end of the course, students in Prof. Baldwin's Introductory Java Programming
classes at ACC are responsible for knowing and understanding the material in this lesson
(except that they are not responsible for detailed information that is specific to C++).

The detailed material on C++ is provided as supplementary material for the benefit of
persons who are already familiar with C++ and who are making the transition into Java.

This lesson is designed primarily as a reading assignment. It is not likely that Prof.
Baldwin will spend any class time discussing the material in this lesson. However, he will
respond to specific questions from students regarding the material in this lesson as long
as those questions pertain to Java and not to C++.

This lesson is intended to be general in nature. Therefore, no effort has been expended to
keep it in compliance with any particular version of the Java JDK.

Introduction
This lesson introduces you to Java programming by presenting some of the similarities
and differences between Java and C++.

An Initial Word about Java and C++


Please see the material in the Preface, which discusses the relationship between Java and
C++ insofar as this course of study is concerned. In general, students in Prof. Baldwin's
Java classes are not required to have any knowledge of C++.
Similarities and Differences
This list of similarities and differences is based heavily on The Java Language
Environment, A White Paper by James Gosling and Henry McGilton
http://java.sun.com/doc/language_environment/ and the soon-to-be published book,
Thinking in Java by Bruce Eckel, http://www.EckelObjects.com/. At least these were the
correct URLs at one point in time. Be aware, however, that the web is a dynamic
environment and the URLs may change in the future.

Java does not support typedefs, defines, or a preprocessor. Without a preprocessor, there
are no provisions for including header files.

Since Java does not have a preprocessor there is no concept of #define macros or
manifest constants. However, the declaration of named constants is supported in Java
through use of the final keyword.

Java does not support enums but, as mentioned above, does support named constants.

Java supports classes, but does not support structures or unions.

All stand-alone C++ programs require a function named main and can have numerous
other functions, including both stand-alone functions and functions, which are members
of a class. There are no stand-alone functions in Java. Instead, there are only functions
that are members of a class, usually called methods. Global functions and global data are
not allowed in Java.

All classes in Java ultimately inherit from the Object class. This is significantly different
from C++ where it is possible to create inheritance trees that are completely unrelated to
one another.

All function or method definitions in Java are contained within the class definition. To a
C++ programmer, they may look like inline function definitions, but they aren't. Java
doesn't allow the programmer to request that a function be made inline, at least not
directly.

Both C++ and Java support class (static) methods or functions that can be called without
the requirement to instantiate an object of the class.

The interface keyword in Java is used to create the equivalence of an abstract base class
containing only method declarations and constants. No variable data members or method
definitions are allowed. (True abstract base classes can also be created in Java.) The
interface concept is not supported by C++.

Java does not support multiple inheritance. To some extent, the interface feature
provides the desirable features of multiple inheritance to a Java program without some of
the underlying problems.
While Java does not support multiple inheritance, single inheritance in Java is similar to
C++, but the manner in which you implement inheritance differs significantly, especially
with respect to the use of constructors in the inheritance chain.

In addition to the access specifiers applied to individual members of a class, C++ allows
you to provide an additional access specifier when inheriting from a class. This latter
concept is not supported by Java.

Java does not support the goto statement (but goto is a reserved word). However, it does
support labeled break and continue statements, a feature not supported by C++. In
certain restricted situations, labeled break and continue statements can be used where a
goto statement might otherwise be used.

Java does not support operator overloading.

Java does not support automatic type conversions (except where guaranteed safe).

Unlike C++, Java has a String type, and objects of this type are immutable (cannot be
modified). Quoted strings are automatically converted into String objects. Java also has a
StringBuffer type. Objects of this type can be modified, and a variety of string
manipulation methods are provided.

Unlike C++, Java provides true arrays as first-class objects. There is a length member,
which tells you how big the array is. An exception is thrown if you attempt to access an
array out of bounds. All arrays are instantiated in dynamic memory and assignment of
one array to another is allowed. However, when you make such an assignment, you
simply have two references to the same array. Changing the value of an element in the
array using one of the references changes the value insofar as both references are
concerned.

Unlike C++, having two "pointers" or references to the same object in dynamic memory
is not necessarily a problem (but it can result in somewhat confusing results). In Java,
dynamic memory is reclaimed automatically, but is not reclaimed until all references to
that memory become NULL or cease to exist. Therefore, unlike in C++, the allocated
dynamic memory cannot become invalid for as long as it is being referenced by any
reference variable.

Java does not support pointers (at least it does not allow you to modify the address
contained in a pointer or to perform pointer arithmetic). Much of the need for pointers
was eliminated by providing types for arrays and strings. For example, the oft-used C++
declaration char* ptr needed to point to the first character in a C++ null-terminated
"string" is not required in Java, because a string is a true object in Java.

A class definition in Java looks similar to a class definition in C++, but there is no closing
semicolon. Also forward reference declarations that are sometimes required in C++ are
not required in Java.
The scope resolution operator (::) required in C++ is not used in Java. The dot is used to
construct all fully-qualified references. Also, since there are no pointers, the pointer
operator (->) used in C++ is not required in Java.

In C++, static data members and functions are called using the name of the class and the
name of the static member connected by the scope resolution operator. In Java, the dot is
used for this purpose.

Like C++, Java has primitive types such as int, float, etc. Unlike C++, the size of each
primitive type is the same regardless of the platform. There is no unsigned integer type in
Java. Type checking and type requirements are much tighter in Java than in C++.

Unlike C++, Java provides a true boolean type.

Conditional expressions in Java must evaluate to boolean rather than to integer, as is the
case in C++. Statements such as if(x+y)... are not allowed in Java because the
conditional expression doesn't evaluate to a boolean.

The char type in C++ is an 8-bit type that maps to the ASCII (or extended ASCII)
character set. The char type in Java is a 16-bit type and uses the Unicode character set
(the Unicode values from 0 through 127 match the ASCII character set). For information
on the Unicode character set see http://www.stonehand.com/unicode.html.

Unlike C++, the >> operator in Java is a "signed" right bit shift, inserting the sign bit into
the vacated bit position. Java adds an operator that inserts zeros into the vacated bit
positions.

C++ allows the instantiation of variables or objects of all types either at compile time in
static memory or at run time using dynamic memory. However, Java requires all variables
of primitive types to be instantiated at compile time, and requires all objects to be
instantiated in dynamic memory at runtime. Wrapper classes are provided for all
primitive types except byte and short to allow them to be instantiated as objects in
dynamic memory at runtime if needed.

C++ requires that classes and functions be declared before they are used. This is not
necessary in Java.

The "namespace" issues prevalent in C++ are handled in Java by including everything in
a class, and collecting classes into packages.

C++ requires that you re-declare static data members outside the class. This is not
required in Java.

In C++, unless you specifically initialize variables of primitive types, they will contain
garbage. Although local variables of primitive types can be initialized in the declaration,
primitive data members of a class cannot be initialized in the class definition in C++.
In Java, you can initialize primitive data members in the class definition. You can also
initialize them in the constructor. If you fail to initialize them, they will be initialized to
zero (or equivalent) automatically.

Like C++, Java supports constructors that may be overloaded. As in C++, if you fail to
provide a constructor, a default constructor will be provided for you. If you provide a
constructor, the default constructor is not provided automatically.

All objects in Java are passed by reference, eliminating the need for the copy constructor
used in C++.

(In reality, all parameters are passed by value in Java. However, passing a copy of a
reference variable makes it possible for code in the receiving method to access the object
referred to by the variable, and possibly to modify the contents of that object. However,
code in the receiving method cannot cause the original reference variable to refer to a
different object.)

There are no destructors in Java. Unused memory is returned to the operating system by
way of a garbage collector, which runs in a different thread from the main program. This
leads to a whole host of subtle and extremely important differences between Java and
C++.

Like C++, Java allows you to overload functions. However, default arguments are not
supported by Java.

Unlike C++, Java does not support templates. Thus, there are no generic functions or
classes.

Unlike C++, several "data structure" classes are contained in the "standard" version of
Java. More specifically, they are contained in the standard class library that is distributed
with the Java Development Kit (JDK). For example, the standard version of Java
provides the containers Vector and Hashtable that can be used to contain any object
through recognition that any object is an object of type Object. However, to use these
containers, you must perform the appropriate upcasting and downcasting, which may
lead to efficiency problems.

Multithreading is a standard feature of the Java language.

Although Java uses the same keywords as C++ for access control: private, public, and
protected, the interpretation of these keywords is significantly different between Java
and C++.

There is no virtual keyword in Java. All non-static methods always use dynamic binding,
so the virtual keyword isn't needed for the same purpose that it is used in C++.
Java provides the final keyword that can be used to specify that a method cannot be
overridden and that it can be statically bound. (The compiler may elect to make it inline
in this case.)

The detailed implementation of the exception handling system in Java is significantly


different from that in C++.

Unlike C++, Java does not support operator overloading. However, the (+) and (+=)
operators are automatically overloaded to concatenate strings, and to convert other types
to string in the process.

As in C++, Java applications can call functions written in another language. This is
commonly referred to as native methods. However, applets cannot call native methods.

Unlike C++, Java has built-in support for program documentation. Specially written
comments can be automatically stripped out using a separate program named javadoc to
produce program documentation.

Generally Java is more robust than C++ due to the following:

• Object handles (references) are automatically initialized to null.


• Handles are checked before accessing, and exceptions are thrown in the event of
problems.
• You cannot access an array out of bounds.
• Memory leaks are prevented by automatic garbage collection.

-end-

www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html

Comparing C++ and Java


Many developers already have experience with an object-oriented
programming language like C++. As you make the transition to Java,
you will encounter many differences, despite some strong similarities.
In this excerpt from "Thinking in Java", Bruce Eckel highlights the
important differences that C++ programmers should be aware of.

As a C++ programmer, you already have the basic idea of object-oriented programming,
and the syntax of Java no doubt looks familiar to you. This makes sense since Java was
derived from C++. However, there are a surprising number of differences between C++
and Java.

These differences are intended to be significant improvements, and if you understand the
differences you'll see why Java is such a beneficial programming language. This article
takes you through the important features that distinguish Java from C++.
1. The biggest potential stumbling block is speed: interpreted Java runs in the range
of 20 times slower than C. Nothing prevents the Java language from being
compiled and there are just-in-time compilers appearing at this writing that offer
significant speed-ups. It is not inconceivable that full native compilers will appear
for the more popular platforms, but without those there are classes of problems
that will be insoluble with Java because of the speed issue.
2. Java has both kinds of comments like C++ does.
3. Everything must be in a class. There are no global functions or global data. If you
want the equivalent of globals, make static methods and static data within a class.
There are no structs or enumerations or unions, only classes.
4. All method definitions are defined in the body of the class. Thus, in C++ it would
look like all the functions are inlined, but they’re not (inlines are noted later).
5. Class definitions are roughly the same form in Java as in C++, but there’s no
closing semicolon. There are no class declarations of the form class foo, only
class definitions.
6. class aType {
7. void aMethod( ) { /* method body */ }
8. }
9. There’s no scope resolution operator :: in Java. Java uses the dot for everything,
but can get away with it since you can define elements only within a class. Even
the method definitions must always occur within a class, so there is no need for
scope resolution there either. One place where you’ll notice the difference is in the
calling of static methods: you say ClassName.methodName( );. In addition,
package names are established using the dot, and to perform a kind of C++
#include you use the import keyword. For example: import java.awt.*;.
(#include does not directly map to import, but it has a similar feel to it).
10. Java, like C++, has primitive types for efficient access. In Java, these are boolean,
char, byte, short, int, long, float, and double. All the primitive types have
specified sizes that are machine independent for portability. (This must have some
impact on performance, varying with the machine.) Type-checking and type
requirements are much tighter in Java. For example:

1. Conditional expressions can be only boolean, not integral.

2. The result of an expression like X + Y must be used; you can’t just say "X + Y"
for the side effect.
11. The char type uses the international 16-bit Unicode character set, so it can
automatically represent most national characters.
12. Static quoted strings are automatically converted into String objects. There is no
independent static character array string like there is in C and C++.
13. Java adds the triple right shift >>> to act as a "logical" right shift by inserting
zeroes at the top end; the >> inserts the sign bit as it shifts (an "arithmetic" shift).
14. Although they look similar, arrays have a very different structure and behavior in
Java than they do in C++. There’s a read-only length member that tells you how
big the array is, and run-time checking throws an exception if you go out of
bounds. All arrays are created on the heap, and you can assign one array to
another (the array handle is simply copied). The array identifier is a first-class
object, with all of the methods commonly available to all other objects.
15. All objects of non-primitive types can be created only via new. There’s no
equivalent to creating non-primitive objects "on the stack" as in C++. All
primitive types can be created only on the stack, without new. There are wrapper
classes for all primitive classes so that you can create equivalent heap-based
objects via new. (Arrays of primitives are a special case: they can be allocated via
aggregate initialization as in C++, or by using new.)
16. No forward declarations are necessary in Java. If you want to use a class or a
method before it is defined, you simply use it – the compiler ensures that the
appropriate definition exists. Thus you don’t have any of the forward referencing
issues that you do in C++.
17. Java has no preprocessor. If you want to use classes in another library, you say
import and the name of the library. There are no preprocessor-like macros.
18. Java uses packages in place of namespaces. The name issue is taken care of by
putting everything into a class and by using a facility called "packages" that
performs the equivalent namespace breakup for class names. Packages also
collect library components under a single library name. You simply import a
package and the compiler takes care of the rest.
19. Object handles defined as class members are automatically initialized to null.
Initialization of primitive class data members is guaranteed in Java; if you don’t
explicitly initialize them they get a default value (a zero or equivalent). You can
initialize them explicitly, either when you define them in the class or in the
constructor. The syntax makes more sense than that for C++, and is consistent for
static and non-static members alike. You don’t need to externally define storage
for static members like you do in C++.
20. There are no Java pointers in the sense of C and C++. When you create an object
with new, you get back a reference (which I’ve been calling a handle in this
book). For example:
String s = new String("howdy");

However, unlike C++ references that must be initialized when created and cannot
be rebound to a different location, Java references don’t have to be bound at the
point of creation. They can also be rebound at will, which eliminates part of the
need for pointers. The other reason for pointers in C and C++ is to be able to point
at any place in memory whatsoever (which makes them unsafe, which is why Java
doesn’t support them). Pointers are often seen as an efficient way to move through
an array of primitive variables; Java arrays allow you to do that in a safer fashion.
The ultimate solution for pointer problems is native methods (discussed in
Appendix A). Passing pointers to methods isn’t a problem since there are no
global functions, only classes, and you can pass references to objects.
The Java language promoters initially said "No pointers!", but when many
programmers questioned how you can work without pointers, the promoters
began saying "Restricted pointers." You can make up your mind whether it’s
"really" a pointer or not. In any event, there’s no pointer arithmetic.
21. Java has constructors that are similar to constructors in C++. You get a default
constructor if you don’t define one, and if you define a non-default constructor,
there’s no automatic default constructor defined for you, just like in C++. There
are no copy constructors, since all arguments are passed by reference.
22. There are no destructors in Java. There is no "scope" of a variable per se, to
indicate when the object’s lifetime is ended – the lifetime of an object is
determined instead by the garbage collector. There is a finalize( ) method that’s a
member of each class, something like a C++ destructor, but finalize( ) is called by
the garbage collector and is supposed to be responsible only for releasing
"resources" (such as open files, sockets, ports, URLs, etc). If you need something
done at a specific point, you must create a special method and call it, not rely
upon finalize( ). Put another way, all objects in C++ will be (or rather, should be)
destroyed, but not all objects in Java are garbage collected. Because Java doesn’t
support destructors, you must be careful to create a cleanup method if it’s
necessary and to explicitly call all the cleanup methods for the base class and
member objects in your class.
23. Java has method overloading that works virtually identically to C++ function
overloading.
24. Java does not support default arguments.
25. There’s no goto in Java. The one unconditional jump mechanism is the break
label or continue label, which is used to jump out of the middle of multiply-
nested loops.
26. Java uses a singly-rooted hierarchy, so all objects are ultimately inherited from the
root class Object. In C++, you can start a new inheritance tree anywhere, so you
end up with a forest of trees. In Java you get a single ultimate hierarchy. This can
seem restrictive, but it gives a great deal of power since you know that every
object is guaranteed to have at least the Object interface. C++ appears to be the
only OO language that does not impose a singly rooted hierarchy.
27. Java has no templates or other implementation of parameterized types. There is a
set of collections: Vector, Stack, and Hashtable that hold Object references, and
through which you can satisfy your collection needs, but these collections are not
designed for efficiency like the C++ Standard Template Library (STL). The new
collections in Java 1.2 are more complete, but still don’t have the same kind of
efficiency as template implementations would allow.
28. Garbage collection means memory leaks are much harder to cause in Java, but not
impossible. (If you make native method calls that allocate storage, these are
typically not tracked by the garbage collector.) However, many memory leaks and
resouce leaks can be tracked to a badly written finalize( ) or to not releasing a
resource at the end of the block where it is allocated (a place where a destructor
would certainly come in handy). The garbage collector is a huge improvement
over C++, and makes a lot of programming problems simply vanish. It might
make Java unsuitable for solving a small subset of problems that cannot tolerate a
garbage collector, but the advantage of a garbage collector seems to greatly
outweigh this potential drawback.
29. Java has built-in multithreading support. There’s a Thread class that you inherit
to create a new thread (you override the run( ) method). Mutual exclusion occurs
at the level of objects using the synchronized keyword as a type qualifier for
methods. Only one thread may use a synchronized method of a particular object
at any one time. Put another way, when a synchronized method is entered, it first
"locks" the object against any other synchronized method using that object and
"unlocks" the object only upon exiting the method. There are no explicit locks;
they happen automatically. You’re still responsible for implementing more
sophisticated synchronization between threads by creating your own "monitor"
class. Recursive synchronized methods work correctly. Time slicing is not
guaranteed between equal priority threads.
30. Instead of controlling blocks of declarations like C++ does, the access specifiers
(public, private, and protected) are placed on each definition for each member
of a class. Without an explicit access specifier, an element defaults to "friendly,"
which means that it is accessible to other elements in the same package
(equivalent to them all being C++ friends) but inaccessible outside the package.
The class, and each method within the class, has an access specifier to determine
whether it’s visible outside the file. Sometimes the private keyword is used less
in Java because "friendly" access is often more useful than excluding access from
other classes in the same package. (However, with multithreading the proper use
of private is essential.) The Java protected keyword means "accessible to
inheritors and to others in this package." There is no equivalent to the C++
protected keyword that means "accessible to inheritors only" (private protected
used to do this, but the use of that keyword pair was removed).
31. Nested classes. In C++, nesting a class is an aid to name hiding and code
organization (but C++ namespaces eliminate the need for name hiding). Java
packaging provides the equivalence of namespaces, so that isn’t an issue. Java 1.1
has inner classes that look just like nested classes. However, an object of an inner
class secretly keeps a handle to the object of the outer class that was involved in
the creation of the inner class object. This means that the inner class object may
access members of the outer class object without qualification, as if those
members belonged directly to the inner class object. This provides a much more
elegant solution to the problem of callbacks, solved with pointers to members in
C++.
32. Because of inner classes described in the previous point, there are no pointers to
members in Java.
33. No inline methods. The Java compiler might decide on its own to inline a method,
but you don’t have much control over this. You can suggest inlining in Java by
using the final keyword for a method. However, inline functions are only
suggestions to the C++ compiler as well.
34. Inheritance in Java has the same effect as in C++, but the syntax is different. Java
uses the extends keyword to indicate inheritance from a base class and the super
keyword to specify methods to be called in the base class that have the same name
as the method you’re in. (However, the super keyword in Java allows you to
access methods only in the parent class, one level up in the hierarchy.) Base-class
scoping in C++ allows you to access methods that are deeper in the hierarchy).
The base-class constructor is also called using the super keyword. As mentioned
before, all classes are ultimately automatically inherited from Object. There’s no
explicit constructor initializer list like in C++, but the compiler forces you to
perform all base-class initialization at the beginning of the constructor body and it
won’t let you perform these later in the body. Member initialization is guaranteed
through a combination of automatic initialization and exceptions for uninitialized
object handles.
35.public class Foo extends Bar
36.{
37. public Foo(String msg) {
38. super(msg); // Calls base constructor
39. }
40.
41. public baz(int i) { // Override
42. super.baz(i); // Calls base method
43. }
44.}
45. Inheritance in Java doesn’t change the protection level of the members in the base
class. You cannot specify public, private, or protected inheritance in Java, as
you can in C++. Also, overridden methods in a derived class cannot reduce the
access of the method in the base class. For example, if a method is public in the
base class and you override it, your overridden method must also be public (the
compiler checks for this).
46. Java provides the interface keyword, which creates the equivalent of an abstract
base class filled with abstract methods and with no data members. This makes a
clear distinction between something designed to be just an interface and an
extension of existing functionality via the extends keyword. It’s worth noting that
the abstract keyword produces a similar effect in that you can’t create an object
of that class. An abstract class may contain abstract methods (although it isn’t
required to contain any), but it is also able to contain implementations, so it is
restricted to single inheritance. Together with interfaces, this scheme prevents the
need for some mechanism like virtual base classes in C++.

To create a version of the interface that can be instantiated, use the implements
keyword, whose syntax looks like inheritance:
47.public interface Face {
48. public void smile();
49.}
50.
51.public class Baz extends Bar implements Face {
52. public void smile( ) {
53. System.out.println("a warm smile");
54. }
55.}
56. There’s no virtual keyword in Java because all non-static methods always use
dynamic binding. In Java, the programmer doesn’t have to decide whether to use
dynamic binding. The reason virtual exists in C++ is so you can leave it off for a
slight increase in efficiency when you’re tuning for performance (or, put another
way, "If you don’t use it, you don’t pay for it"), which often results in confusion
and unpleasant surprises. The final keyword provides some latitude for efficiency
tuning – it tells the compiler that this method cannot be overridden, and thus that
it may be statically bound (and made inline, thus using the equivalent of a C++
non-virtual call). These optimizations are up to the compiler.
57. Java doesn’t provide multiple inheritance (MI), at least not in the same sense that
C++ does. Like protected, MI seems like a good idea but you know you need it
only when you are face to face with a certain design problem. Since Java uses a
singly-rooted hierarchy, you’ll probably run into fewer situations in which MI is
necessary. The interface keyword takes care of combining multiple interfaces.
58. Run-time type identification functionality is quite similar to that in C++. To get
information about handle X, you can say, for example:
X.getClass().getName();

To perform a type-safe downcast you say:


derived d = (derived)base;

just like an old-style C cast. The compiler automatically invokes the dynamic
casting mechanism without requiring extra syntax. Although this doesn’t have the
benefit of easy location of casts as in C++ "new casts," Java checks usage and
throws exceptions so it won’t allow bad casts like C++ does.
59. Exception handling in Java is different because there are no destructors. A finally
clause can be added to force execution of statements that perform necessary
cleanup. All exceptions in Java are inherited from the base class Throwable, so
you’re guaranteed a common interface.
60.
61.public void f(Obj b) throws IOException {
62. myresource mr = b.createResource();
63. try {
64. mr.UseResource();
65.
66. } catch (MyException e) {
67. // handle my exception
68. } catch (Throwable e) {
69. // handle all other exceptions
70. } finally {
71. mr.dispose(); // special cleanup
72. }
}

73. Exception specifications in Java are vastly superior to those in C++. Instead of the
C++ approach of calling a function at run-time when the wrong exception is
thrown, Java exception specifications are checked and enforced at compile-time.
In addition, overridden methods must conform to the exception specification of
the base-class version of that method: they can throw the specified exceptions or
exceptions derived from those. This provides much more robust exception-
handling code.
74. Java has method overloading, but no operator overloading. The String class does
use the + and += operators to concatenate strings and String expressions use
automatic type conversion, but that’s a special built-in case.
75. The const issues in C++ are avoided in Java by convention. You pass only
handles to objects and local copies are never made for you automatically. If you
want the equivalent of C++’s pass-by-value, you call clone( ) to produce a local
copy of the argument (although the clone( ) mechanism is somewhat poorly
designed – see Chapter 12). There’s no copy-constructor that’s automatically
called.

To create a compile-time constant value, you say, for example:

static final int SIZE = 255;


static final int BSIZE = 8 * SIZE;
76. Because of security issues, programming an "application" is quite different from
programming an "applet." A significant issue is that an applet won’t let you write
to disk, because that would allow a program downloaded from an unknown
machine to trash your disk. This changes somewhat with Java 1.1 digital signing,
which allows you to unequivocally know everyone that wrote all the programs
that have special access to your system (one of which might have trashed your
disk; you still have to figure out which one and what to do about it.). Java 1.2 also
promises more power for applets
77. Since Java can be too restrictive in some cases, you could be prevented from
doing important tasks such as directly accessing hardware. Java solves this with
native methods that allow you to call a function written in another language
(currently only C and C++ are supported). Thus, you can always solve a platform-
specific problem (in a relatively non-portable fashion, but then that code is
isolated). Applets cannot call native methods, only applications.
78. Java has built-in support for comment documentation, so the source code file can
also contain its own documentation, which is stripped out and reformatted into
HTML via a separate program. This is a boon for documentation maintenance and
use.
79. Java contains standard libraries for solving specific tasks. C++ relies on non-
standard third-party libraries. These tasks include (or will soon include):
o Networking
o Database Connection (via JDBC)
o Multithreading
o Distributed Objects (via RMI and CORBA)
o Compression
o Commerce

The availability and standard nature of these libraries allow for more rapid
application development.

80. Java 1.1 includes the Java Beans standard, which is a way to create components
that can be used in visual programming environments. This promotes visual
components that can be used under all vendor’s development environments. Since
you aren’t tied to a particular vendor’s design for visual components, this should
result in greater selection and availability of components. In addition, the design
for Java Beans is simpler for programmers to understand; vendor-specific
component frameworks tend to involve a steeper learning curve.
81. If the access to a Java handle fails, an exception is thrown. This test doesn’t have
to occur right before the use of a handle; the Java specification just says that the
exception must somehow be thrown. Many C++ runtime systems can also throw
exceptions for bad pointers.
82. Generally, Java is more robust, via:
o Object handles initialized to null (a keyword)
o Handles are always checked and exceptions are thrown for failures
o All array accesses are checked for bounds violations
o Automatic garbage collection prevents memory leaks
o Clean, relatively fool-proof exception handling
o Simple language support for multithreading
o Bytecode verification of network applets

www.daniweb.com/techtalkforums/thread22036.html
Differences Between Java and C/C++

• The Preprocessor
• Pointers
• Structures and Unions
• Functions
• Multiple Inheritance
• Strings
• The goto Statement
• Operator Overloading
• Automatic Coercions
• Variable Arguments
• Command-Line Arguments

It is no secret that the Java language is highly derived from the C and C++ languages. Because
C++ is currently considered the language of choice for professional software developers, it's
important to understand what aspects of C++ Java inherits. Of possibly even more importance are
what aspects of C++ Java doesn't support. Because Java is an entirely new language, it was
possible for the language architects to pick and choose which features from C++ to implement in
Java and how.

The focus of this appendix is to point out the differences between Java and C++. If you are a C++
programmer, you will be able to appreciate the differences between Java and C++. Even if you don't
have any C++ experience, you can gain some insight into the Java language by understanding what
C++ discrepancies it clears up in its implementation. Because C++ backwardly supports C, many of
the differences pointed out in this appendix refer to C++, but inherently apply to C as well.

The Preprocessor

All C/C++ compilers implement a stage of compilation known as the preprocessor. The C++
preprocessor basically performs an intelligent search and replace on identifiers that have been
declared using the #define or #typedef directives. Although most advocates of C++ discourage the
use of the preprocessor, which was inherited from C, it is still widely used by most C++
programmers. Most of the processor definitions in C++ are stored in header files, which
complement the actual source code files.

The problem with the preprocessor approach is that it provides an easy way for programmers to
inadvertently add unnecessary complexity to a program. What happens is that many programmers
using the #define and #typedef directives end up inventing their own sublanguage within the
confines of a particular project. This results in other programmers having to go through the header
files and sort out all the #define and #typedef information to understand a program, which makes
code maintenance and reuse almost impossible. An additional problem with the preprocessor
approach is that it is weak when it comes to type checking and validation.

Java does not have a preprocessor. It provides similar functionality (#define, #typedef, and so on)
to that provided by the C++ preprocessor, but with far more control. Constant data members are
used in place of the #define directive, and class definitions are used in lieu of the #typedef
directive. The result is that Java source code is much more consistent and easier to read than C++
source code. Additionally, Java programs don't use header files; the Java compiler builds class
definitions directly from the source code files, which contain both class definitions and method
implementations.

Pointers

Most developers agree that the misuse of pointers causes the majority of bugs in C/C++
programming. Put simply, when you have pointers, you have the ability to trash memory. C++
programmers regularly use complex pointer arithmetic to create and maintain dynamic data
structures. In return, C++ programmers spend a lot of time hunting down complex bugs caused by
their complex pointer arithmetic.

The Java language does not support pointers. Java provides similar functionality by making heavy
use of references. Java passes all arrays and objects by reference. This approach prevents common
errors due to pointer mismanagement. It also makes programming easier in a lot of ways simply
because the correct usage of pointers is easily misunderstood by all but the most seasoned
programmers.

You may be thinking that the lack of pointers in Java will keep you from being able to implement
many data structures, such as dynamic arrays. The reality is that any pointer task can be carried
out just as easily and more reliably with objects and arrays of objects. You then benefit from the
security provided by the Java runtime system; it performs boundary checking on all array indexing
operations.

Structures and Unions


There are three types of complex data types in C++: classes, structures, and unions. Java only
implements one of these data types: classes. Java forces programmers to use classes when the
functionality of structures and unions is desired. Although this sounds like more work for the
programmer, it actually ends up being more consistent, because classes can imitate structures and
unions with ease. The Java designers really wanted to keep the language simple, so it only made
sense to eliminate aspects of the language that overlapped.

Functions

In C, code is organized into functions, which are global subroutines accessible to a program. C++
added classes and in doing so provided class methods, which are functions that are connected to
classes. C++ class methods are very similar to Java class methods. However, because C++ still
supports C, there is nothing discouraging C++ programmers from using functions. This results in a
mixture of function and method use that makes for confusing programs.

Java has no functions. Being a purer object-oriented language than C++, Java forces programmers
to bundle all routines into class methods. There is no limitation imposed by forcing programmers to
use methods instead of functions. As a matter of fact, implementing routines as methods
encourages programmers to organize code better. Keep in mind that strictly speaking there is
nothing wrong with the procedural approach of using functions; it just doesn't mix well with the
object-oriented paradigm that defines the core of Java.

Multiple Inheritance

Multiple inheritance is a feature of C++ that allows you to derive a class from multiple parent
classes. Although multiple inheritance is indeed powerful, it is complicated to use correctly and
causes many problems otherwise. It is also very complicated to implement from the compiler
perspective.

Java takes the high road and provides no direct support for multiple inheritance. You can implement
functionality similar to multiple inheritance by using interfaces in Java. Java interfaces provide
object method descriptions but contain no implementations.

Strings

C and C++ have no built-in support for text strings. The standard technique adopted among C and
C++ programmers is that of using null-terminated arrays of characters to represent strings.

In Java, strings are implemented as first class objects (String and StringBuffer), meaning that they
are at the core of the Java language. Java's implementation of strings as objects provides several
advantages:
• The manner in which you create strings and access the elements of strings is consistent
across all strings on all systems
• Because the Java string classes are defined as part of the Java language and not part of
some extraneous extension, Java strings function predictably every time
• The Java string classes perform extensive runtime checking, which helps eliminate
troublesome runtime errors

The goto Statement

The dreaded goto statement is pretty much a relic these days even in C and C++, but it is
technically a legal part of the languages. The goto statement has historically been cited as the cause
for messy, impossible to understand, and sometimes even impossible to predict code known as
"spaghetti code." The primary usage of the goto statement has merely been as a convenience to
substitute not thinking through an alternative, more structured branching technique.

For all these reasons and more, Java does not provide a goto statement. The Java language
specifies goto as a keyword, but its usage is not supported. I suppose the Java designers wanted to
eliminate the possibility of even using goto as an identifier! Not including goto in the Java language
simplifies the language and helps eliminate the option of writing messy code.

Operator Overloading

Operator overloading, which is considered a prominent feature in C++, is not supported in Java.
Although roughly the same functionality can be implemented by classes in Java, the convenience of
operator overloading is still missing. However, in defense of Java, operator overloading can
sometimes get very tricky. No doubt the Java developers decided not to support operator
overloading to keep the Java language as simple as possible.

Automatic Coercions

Automatic coercion refers to the implicit casting of data types that sometimes occurs in C and C++.
For example, in C++ you can assign a float value to an int variable, which can result in a loss of
information. Java does not support C++ style automatic coercions. In Java, if a coercion will result
in a loss of data, you must always explicitly cast the data element to the new type.

Variable Arguments

C and C++ let you declare functions, such as printf, that take a variable number of arguments.
Although this is a convenient feature, it is impossible for the compiler to thoroughly type check the
arguments, which means problems can arise at runtime without you knowing. Again Java takes the
high road and doesn't support variable arguments at all.

Command-Line Arguments

The command-line arguments passed from the system into a Java program differ in a couple of
ways from the command-line arguments passed into a C++ program. First, the number of
parameters passed differs between the two languages. In C and C++, the system passes two
arguments to a program: argc and argv. argc specifies the number of arguments stored in argv.
argv is a pointer to an array of characters containing the actual arguments. In Java, the system
passes a single value to a program: args. args is an array of Strings that contains the command-line
arguments. In C and C++, the command-line arguments passed into a program include the name
used to invoke the program. This name always appears as the first argument and is rarely ever
used. In Java, you already know the name of the program because it is the same name as the class,
so there is no need to pass this information as a command-line argument. Therefore, the Java
runtime system only passes the arguments following the name that invoked the program.

www.csupomona.edu/~dlbell/cppexplanationsfa99/23.html
In the evolution of Java, B gave birth to C. C evolved into C++, and C++ transmuted into
Java. Java is the language of the Internet. It was conceived by James Gosling, Patrick
Naughton, and Mike Sheridan at Sun Microsystems, Inc. in 1990 and took five years to
develop.

Java can be used to create two types of programs: applications and applets. The output of
a Java compiler is not executable code. Rather it is bytecode. Java run-time system is an
interpreter for bytecode. It is simply a highly efficient means of encoding a program for
interpretation. It is much easier to allow Java programs to run in a wide variety of
environments. Once the run-time package exists for a given system, the bytecode version
of any Java program can run on it. Therefore, using bytecode to represent programs is the
easiest way to create truly portable programs.

There are two surface similarities between Java and C++. First, Java uses a syntax similar
to C++, such as the general forms of the for, while, and do loops. Second, Java supports
object-oriented programming, same way as C++.

There are also significant differences from C++, which fundamentally makes Java
distinct from C++. Perhaps the single biggest difference between Java and C++ is that
Java does not support pointers. Pointers are inherently insecure and troublesome. Since
pointers do not exist in Java, neither does the -> operator. Some other C++ features are
not found in Java.

Java does not include structures or unions because the class encompasses• these other
forms. It is redundant to include them.
Java does not support• operator overloading.
Java does not include a preprocessor or support the• preprocessor directives.
Java does not perform any automatic type• conversions that result in a loss of precision.
All the code in a Java• program is encapsulated within one or more classes. Therefore,
Java does not have global variables or global functions.
Java does not support multiple• inheritance.
Java does not support destructors, but rather, add the• finalize() function.
Java does not have the delete operator.•
The• << and >> are not overloaded for I/O operations.
Java does not• support templates.

Java shares many similarities with C++ as it relates to classes, but there are also several
differences. By default, members of a class are accessible by other members of their
class, derived classes, and by other members of their package. Therefore, class members
are “more public” than they are in C++, however, the private access specifier applies only
to the variable or method that it immediately precedes. All class objects are instantiated in
Java using the new operator. Therefore, all class objects are dynamically allocated. When
there are no references to an object, then the object is considered inactive.
Java includes two class-management features that help make using and organizing classes
easier. The first is called a package, which defines a scope. Therefore, names declared
inside a package are private to that package. Java uses file directories to store packages.
Therefore, each package must be stored in a directory that has the same name as the
package—including capitalization.

Java, like C++, supports hierarchies of classes. However, the way that inheritance is
implemented in Java differs substantially from the way that it is implemented in C++.
Since multiple inheritance is not allowed in Java, then Java class hierarchies are linear. In
Java, inheritance is referred to as subclassing. A base class in C++ is referred to as
superclass in Java.

www.objectmentor.com/resources/articles/javacpp.pdf

Potrebbero piacerti anche