C++&java

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View C++&java as PDF for free.

More details

  • Words: 10,719
  • Pages: 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 is a dynamic array of elements of type T. The instruction vector a;

makes an initially empty vector. The command vector 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 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& 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, [email protected], 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.

-endwww.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 multiplynested 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 exceptionhandling 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 platformspecific 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 nonstandard 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