March 24 notes:

Copy constructors:

In C++ there's a special case for constructors: the copy constructor.  The idea of this one is that it allows you to set a new instance of an object to the value of an existing object.  The prototype of such a constructor (in a .h file) would be as follows:
    classname(const classname& existinginstance);

The body of the copy constructor would simply copy over all of the properties (ie: variables) from the instance passed as an argument into the local copies.
For instance if you have an int named data, you would need the following line inside of the method:
    data = existinginstance.data;

What's special about this form of the constructor is that it is called when you run the 2nd of these two lines of code:
    classname myclass1;
    classname myclass2 = myclass1;

Note: this will ONLY be envoked on lines where you are declaring an instance of a class, if you want a general copy method that works with the = sign, look below to operator overloading.


const:

const is a keyword built into C++ which indicates a variable that should not be modified.  It will basically assert that no changes are allowed to be made.  For instance, if you are writing a function to search through an apvector, there's no real need to modify the values of the apvector, and thus you should probably declare the apvector argument as const.  In reality, this is just another way of saving the world from sloppy programming, but it's something the AP people want you to know, and want you to use when appropriate, so get used to using const on any argument that should not be changed, or on any return value that should not be altered.

Operator overloading:

C++ has many confusing features that gain you very little, but it also has a handful of confusing features which can be kind of neat.  One of these is the idea of operator overloading.  Up until now in order to manipulate classes you write you have to manually tell C++ to run a specific method.  C++ also allows you to overload all of the built in operators to treat them as special kinds of methods for your classes and thus can make your classes look like they are a part of C++'s built in data types!  
The format for a method that can overload an operator in the class definition is as follows:
returntype operator {operator} (arguments) where {operator} is replaced with the operator you are overloading.
For instance, if you want to overload the assignment operator (to make copying easier) you could write the following:

    const myclass& operator =(const myclass& rhs);

it returns a reference to myclass because the assignment operator actually returns a copy of the value the left hand-side of the operator is set to.  
For instance if I say cout << (myint = 2 *6), that will print out 12
the rhs argument will be the instance of the class on the right hand side.  (rhs = right hand side)
So if I have 2 instances of myclass, one names mc1, the other named mc2, and I type the following:

    mc1 = mc2;

this is equivilent to writing
    mc1.operator =(mc2);

(assuming we could directly run that method like that.  We actually can't since operator overloading is a very special case in C++)

The implementation of this method could look like this:

const myclass& myclass::operator =(const myclass &rhs) {
    data = rhs.data; // just copy over all of the data you need to
    return *this;
}

The last line looks very very odd.  It will make more sense when you get into pointers and linked lists, but for right now, whenever you overload an operator and need to return a reference to the current instance of the class, you just need to say return *this, so for now just memorize this special case.

Note: not all operators should return instances of the same class.  For instance, the == operator will normally return a bool

If you wanted to implement a == overload, you could use the following in your .h file

bool operator ==(const myclass &rhs);

while its implementation could look like this:

bool myclass::operator ==(const myclass &rhs) {
    return (data == rhs.data);  
}

and this would be envoked by saying
    if(mc1 == mc2)

In addition, you can get polymorphic with operator overloading!  (joy!)

Let's say you want to be able to add integers into your myclass directly:
you could write the following in your class definition:

const myclass& operator +=(const int rhs);

The implementation could look like this:

const myclass& myclass::operator +=(const int rhs) {
    data += rhs;
    return *this;
}

and you can do this even if you already have another += operator defined that takes in another instance of myclass; C++ will decide which to call depending on if you pass in an integer or a instance of myclass.

For instance, if you say mc1 += 3, C++ knows to go for the one that takes an int as the argument, and if you say mc1 += mc2 it will look for the one that takes an instance of myclass as an argument.  

Wasn't that fun??