|
CS 371
|
Please read Barb Lerner's nice introduction to C++ for Java Programmers for more information on this topic, You might also consider getting a copy of a text such as C for Java Programmers, by Timothy Budd.
For sample code go here
int main(void) //or we could say: int main()
int myArray[10];
// fill in array
for(int i=0;i<10;i++)
myArray[i] = i*i;
// sum values of array (while loop is just for fun)
int i=0;
int sum = 0;
while(i < 10)
sum+=myArray[i];
i++;
The only differences are that the funtion main() is not a method in any class
(and it has a different signature). It is possible to include argv as a
parameter to main, but we postpone this for the moment.
The form of looping and conditional statements of Java and C++ are virtually identical. One difference: in C++ a condition does not have to evaluate to a boolean (or 'bool'). Any non-zero integral value is considered 'true', while 0 is considered 'false'. For example,
int value=7;
if(value)
// do some stuff
As we will learn later, OpenGL is much fussier about this issue than C++ is.
C++ is much more generous about converting betwen types. Given the following definitions:
bool a = false; bool b = true; short s = 2; int i = 100000; float f = 2.3; double d = 1.23456789e+198;we could do the following:
int myList[100]; // or
int yourList[] = {3, 7, 14, -5} // array size is deduced from initializer
If the size of the array is not known at compile time, the definition methods above cannot be used. Moreover, the Java approach below is illegal.
int listSize = getSizeSomehow(); // listSize is not known at compile time int myList[] = new int[size];
How do we dynamically allocate arrays at runtime? This brings us to....
int a=0; int b=2; a = b;copies the value of a into b. This is called value semantics. However,
Point3D p1 = new Point3D(0.0,0.0,0.0); Point3D p2 = new Point3D(1.0, 2.0, 3.1); p1 = p2;copies a reference to p2 into p1, so that now both p1 and p2 "share" the same point object. This is called reference semantics.
Essentially, p1 and p2 can be thought of as pointers to the actual point data. The assignment p1 = p2 just copies p2's pointer to the data to p1. In C++, class types follow the same value semantics as built-in types do, unless the class type is explicitly designed to be a pointer type.
Suppose, for example, we have a class Point3D which has 3 data members:
class Point3D {
public
double x, y, z;
// ... rest of class definition
Then a C++ program could declare p1 and p2 as follows
Point3D p1(0.0,0.0,0.0); Point3D p2(1.0, 2.0, 3.1); p1 = p2;Each of p1 and p2 now hold the same x,y,z values, but they hold their own copies of them, so that assigning p1.x = 5.0 does not change p2.x.
However, what if we want reference semantics--which we may well if our objects are very large and we are passing them as parameters to many functions. C++ allows this through the use of pointers:
Point3D *p1 = new Point3D(0.0,0.0,0.0); Point3D *p2 = new Point3D(1.0, 2.0, 3.1); p1 = p2;The syntax Point3D *p1 specifies that p1 is a pointer to an object of type Point3D (and that *p1 is an object of type Point3D. No space is allocated for the actual point data until new is invoked.
Note that the code below behaves differently than the preceding code.
Point3D *p1 = new Point3D(0.0,0.0,0.0); Point3D *p2 = new Point3D(1.0, 2.0, 3.1); *p1 = *p2;Here the values of the Point3D object *p2 (not just the pointer) are copied to the Point object *p1. Note also that, for example, p1 = *p2 or *p1 = p2 make no sense since one is of type Point3D and the other is of type Point3D* (that is, a pointer to a Point3D).
This pointer device is what we need to dynamically allocate arrays:
int listSize = getSizeSomehow(); // listSize is not known at compile time int *myList = new int[size];We declare myList to be a pointer to an int. Then new int[size] allocates an array of "size" ints and returns a pointer to the first int in the array. We can then treat the symbol myList as if it really were an array:
for(int i=0;i<listSize;i++)
myList[i] = i*i;
double dot(Point3D q1, Point3D q2)
return (q1.x*q2.x + q1.y*q2.y + q1.z*q2.z);
Suppose we invoke dot on Point3D objects p1 and p2.
Then each of p1 and p2 is copied
into q1 and q2. If objects are large, this could be a problem. One solution
would be to redefine the function:
double dot(Point3D *q1, Point3D *q2)
return (q1->x*q2->x + q1->y*q2->y + q1->z*q2->z); // note syntax!
If p1 and p2 were now pointers to Point3D objects, then dot(p1,p2) only copies
the pointer values, not the actual objects, into q1 and q2. But suppose
p1 and p2 are not pointers, but are, in fact, Point3D objects, and that
dot expects to get pointers to Point3D objects.
How could we get pointers to them to pass to dot? By using the
reference operator &:
result = dot(&p1,&p2);
The reference operator has other uses also.
int a = 5; int &b = a; // declares b to be an alias for a (not a pointer!)In the above fragment, b and a shere the same int, so assigning to either a or b changes both. Also, b cannot be made to reference another int.
In this usage, b is called a reference to a. The reference construct gives us another way to pass arguments to functions:
double dot(Point3D &q1, Point3D &q2)
return (q1.x*q2.x + q1.y*q2.y + q1.z*q2.z); // note syntax!
Now invoking dot on Point3D objects p1 and p2 involves no copying:
q1 is a reference to p1 and q2 is a reference to p2. This method of passing
arguments (pass by reference) is very common, but should be used carefully:
if q1 or q2 were modified in dot, then the corresponding point p1 or p2
would also be modified..