Thursday, October 22, 2009

Const in a Nutshell

That heading sure could be misconstrued. Anyway, here are the rules of const:

1. Type const is used for unmodifiable objects.
2. Attempts to modify const objects will cause execution errors.
3. Member functions cannot call const objects unless the function is const.
4. Member functions that modify objects cannot be const.
5. Const member functions cannot call non-const object in the same class instance.
6. You can't use a non-const member function to call a const object.
7. One solution is to overload the const member function with a non-const version.
8. Constructors or destructors can never be const because they change objects.
9. Constructors may still be used to initialize const objects.
10. Const data members and data members referenced by const MUST be initialized in using member initializers.

Wednesday, October 21, 2009

Review of Pointers

Count counter; // create counter object
Count *counterPtr = &counter; // create pointer to counter
Count &counterRef = counter; // create reference to counter

cout << "Set x to 1 and print using the object's name: ";
counter.setX( 1 ); // set data member x to 1
counter.print(); // call member function print

cout << "Set x to 2 and print using a reference to an object: ";
counterRef.setX( 2 ); // set data member x to 2
counterRef.print(); // call member function print

cout << "Set x to 3 and print using a pointer to an object: ";
counterPtr->setX( 3 ); // set data member x to 3
counterPtr->print(); // call member function print

Funky Little ? Operator

cout << ( ( time == 0 time == 12 ) ? 12 )

This means that if time is 0 or time is 12, it will be represented with, or equal 12. Nifty!

Preprocessor Header Files

To avoid header files getting called more than once, use the following code in the header file to create a preprocessor header file:
#ifndef YOURHEADERFILE_H
#define YOURHEADERFILE_H

HERE YOU ADD YOUR MEMBER FUNCTION AND DATA MEMBER PROTOTYPES

//At the VERY end of the header file, type the following to wrap it
//all up like a cheeseburger:
#endif

And that, my friends, is all she wrote!

Tuesday, October 20, 2009

Arrays within Arrays

Doesn't that title just remind you of the Princess Bride, when the lispy priest says, "...Mawiage. That Dweam, within a Dweam." Okay, so consider this problem. You see, in order for me to know I really "Get" it, I have to write it out.

Story: I have run a survey to determine how often people eat find what they are looking for on a website. I have a database full of 100 responses, and let's say, for the sake of simplifying this story, that these 100 responses are pulled out of a database into my array which is 100 response long. I won't go into how they got there, they are just there. (Of course, these can be manually entered, but keep in mind that if the number of initialized values do not match the number in the array, there may be problems. If there are fewer values, the rest will be set to zero. If there are more - well, just make sure there aren't more values than the size of the array.)

Now, the survey asked the following question: "On a scale of 1-10, how likely are you to recommend this website to another person?" After all, isn't that the ultimate representation of satisfaction; that you will recommend the website to someone else? Okay, the responses are recorded thus:

10 very likely - - - - 5 neutral - - - - 1 not at all likely

So next we need an array of ten elements that represent the possible responses. For each element, I now want to know what the tally was for each response.

First I need to set up and initialize these two arrays, right? Array variables HAVE to be type const, but not only do the arrays need to BE type const, they also should TAKE a const variable, and here is why: If the size of the array ever needs to change, I can just change the size of the array at the VERY BEGINNING of the program, and not throughout the function. Saves time in the long run, capisce?

// THESE ARE THOSE VALUES THAT DETERMINE THE SIZE OF THE ARRAY:
const int surveyAnswerSize = 100; // size of surveyAnswer array
const int tallySize = 10; // size of tally array

// HERE IS THE FIRST ARRAY - PRETEND THERE ARE 100 RESPONSES AND THAT THESE WERE FILLED IN FROM A DATABASE:

const int surveyAnswers[ surveyAnswerSize ] = { 10, 3, 4, 7, 9, 8, ........ 9, 8, 10 };

// HERE IS THE SECOND ARRAY - THIS WILL KEEP TRACK A TALLY OF HOW MANY OF EACH RESPONSE THERE WERE:

// initialize tally counters to 0 - remember, the number of elements in
// the array was decided by tallySize above. Why set this to zero? because
// we don't know any information about any of the ten responses yet.
int tally[ tallySize ] = { 0 };

// THIS IS OUR FOR LOOP THAT WILL WALK THROUGH EACH OF THE SURVEY
// ANSWERS AND INCREMENT THE TALLY FOR EACH POSSIBLE RESPONSE. NOTICE
// IN OUR FOR LOOP THAT WE DON"T USE THE ACTUAL NUMBER OF SURVEYANSWERS.

for ( int eachAnswer = 0; eachAnswer < surveyAnswer; eachAnswer++ )
tally[ surveyAnswer[ eachAnswer ] ]++;


So what happens in the above code is this:

starting with eachAnswer, this will be zero, so surveyAnswer will run back and see what the survey value was for element 0. Oh, looks like that will be equal to 10! Okay, so then tally takes a look at that result - - 10, hmmm? Looks like we have one count for the response 10 (which in our world means, highly likely - they will be highly likely to recommed the website.

Well, going back through the for loop, since we haven't yet reached the total initialized for surveyAnswer, eachAnswer has been incremented and now equals 1. What is contained in element 1 of surveyAnswer? Let's go see! Oh, looks like that will equal 3. Which would be on the less satisfied end of the response scale. Tally accepts that three and adds one count for response 3. Again through the for loop, eachAnswer now is incremented to 2. What value does element 2 have in the array surveyAnswer??? Ta-da! It looks like 4. So tally now adds one count for the response 4. At this point if we were to print out the results, it would look like this:

(Number of responses for each possible answer:)

10 = 1
4 = 1
3 = 1

Well, maybe you don't understand it any better, but I think I've got it, Watson!

Sunday, October 18, 2009

Like Lightening! (- or maybe not)

I have four more days to finish my class. I have two chapters to read, and five more programs, and several questions left to answer. I didn't think I would say this so early, but I think I see the light at the end of the tunnel! I hope my assignments are graded well. At least four of the programs are on concepts I already have a basic understanding of - Arrays - thanks to AntiRTFM.

Well, as long as I can avoid major hang-ups, I think I will make it!

Default Parameters

Just a quick "Good-to-know:"

When setting default parameters, don't specify the parameters in both the header and the cpp file, rather specify in one or the other.

For example:
HEADER - prototype:

int popcorn (int oil = 1, int kernels = 50, int heat = 4);

FUNCTION - definition:
int popcorn (int oil, int kernels, int heat)
{
definition
};

Visual Studio Express, Constructors and Pointers - #include "stdafx.h"

I have to admit, constructors have been one of the most challenging pieces of C++ for me to grasp so far - the reason being is that they are so critical to making all of the pieces work when you are trying to take the leap from placing all of the elements of a program in one file, to separating them into different files in true object oriented programming (OOP) fashion. The book I am using is so incredibly vague when explaining constructors, that I found myself piecing together this program based on what was on the book rather than building something because I really understood the concepts. I don't learn well unless I understand all of the underlying concepts, so when I stumbled upon the AntiRTFM tutorials on YouTube, I was delighted. What a great teacher, this fellow is! He really breaks it down and makes difficult topics digestible. Nevermind the imperfect English - he teaches better than many native English speakers I know.

Constructors were covered somewhere between 35-39, I believe, but this video (and a couple of earlier ones jumps into pointers in the memory. He also created this nifty visualization of how storage works behind the scenes. I already understood the storage/memory piece, but who doesn't like a good visualization! C++ Tutorial (44) - Absolute n00b spoonfeed

I thought that maybe my IDE (the tool I use to write code) was just buggy because I couldn't separate the files and get them to run correctly. I even downloaded a second free IDE for C++(CodeBlocks) to run my code to see if that was the problem. Nope. Same errors. Finally I walked through the above AntiRTFM videos carefully and watched for indicators to see what I was doing wrong. As it turns out, the header file must have a declaration of the constructor (with no 'type,' and matching parameters to the defined constructor in the cpp file, with a call to the header file (#include YourClass.h). The main cpp file should also include the header file, but the only thing needed to link the main file to call the constructor is to merely call the class as an instance - like calling an int variable, instead, you just type, for example, "YourClass xyz;." Finally, in the YourClass.cpp file, when defining the constructor, only use ONE constructor. For example:
YourClass::YourClass (int optionalVariable, int optionalVariable2 . . .)
{
Initialize private variables to a number or to one of the optional variables
};

And that is your definition. Remember, in the header file, the constructor parameters must match - for example:

class YourClass
{
public:
YourClass (int, int . . .);
type other functions here
private:
type your private variables here - you will initialize these in the constructor definition.
}

Now, I am using the free version of Visual C++ 2008 Express Edition. The AntiRTFM videos state that you should type #include "stdafx.h" at the beginning of all of your cpp files. If you are using Visual C++ 2008 Express, don't worry about doing this. I doesn't work. Apparently, the express edition doesn't allow for precompiled header directives (like stdafx.h) unless you dish out the 500 something dollars for the enterprise edition, as described in this forum. The files will still compile fine in the express edition, but are just a little slower. For me, when the compiler takes longer, I know I wrote a successful program. Otherwise it returns a lovely error report right away.

Maybe this will save someone the three hours of research I did to find this information. At any rate, I won't forget it!

Purpose of this blog

Hi, I am currently working toward a master's degree in Computer Science. I have a plan. I have a goal, and I am working to achieve it! Not everyone (or maybe anyone) is interested in the gory details of my programming struggles, so this is a place for me to keep notes on my studies, declare my victories, share what I have learned, and share resources I have found to be helpful! Maybe someone will find this information helpful, but more than anything, it will give me a break from my studies to regurgitate what I have learned and have a place to capture it and review it later. Welcome to my C++ Sandbox!