CSCI 261 - Programming Concepts (C++)Fall 2017 - Lab 7BQuick Links: Canvas | CS @ Mines | Cloud9 | Piazza | zyBooks |
|
| Home | Contact | Syllabus | Assignments | Schedule | Resources | | |
This lab is due by Tuesday, November 14, 2017 11:59 PM . ConceptsFocus on defining a Triangle class from scratch.
You should write a
main.cpp function that shows each
feature of your class works as expected (e.g., print out a triangle's
area by calling the area function).Member FunctionsConsider a program that works with photographs.
Photos have a height and a width. We might model such a class like this:
class Photo {
public: Photo(); // Photo constructor function int height; int width; }; Since photos have a height and a width, they
also have an area. What is a photo's area? It's a value generated by multiplying
a Photo object's height and width together. How might we enable our Photo class
such that a Photo object is able to tell us its area? In other words, what do
we need to do in order to be able to write code like the following?
Photo p;
cout << "The area of Photo p is" << p.area() << endl; To support the ability to write
p.area() , we must define area as a member function,
or "a function that belongs to objects of a class." We do this in two steps.
In other words, in the header file Photo.h, we should add:
class Photo {
public: Photo(); // Photo constructor function int area(); // area member function int height; int width; }; And in the implementation file, Photo.cpp, we should add:
int Photo::area() {
return height * width; } The function prototype in Photo.h tells the
machine, "Hey, Photo objects have a member function called area that returns
an int." The function definition in Photo.cpp tells the machine, "Hey, the
definition of the Photo member function area() I told you about in Photo.h
works like this."
Look at the body of the area function above.
Notice how the function, since it is declared "inside" the class, has direct
access to everything else inside the class, such as height and width.
This is so important, we'd like you
to read it again. Look at the body of the area function above. Notice
how the function, since it is declared "inside" the class, has direct access
to everything else inside the class, such as height and width.
When should you use member variables (e.g., height and width)
instead of member functions in your
main.cpp file? We hope you are
starting to see why most seasoned programmers use member functions.Public vs. Private Members In Lab7A, you defined a simple Money class that
used the
public: syntax to tell the machine that the
dollars and cents
properties were "accessible from outside the object." For example,
consider the following code:Photo.h
class Photo {
public: Photo(); int area(); int height; int width; }; Photo.cpp
Photo::Photo() {
height = 8; width = 5; } That
public: thing you see in the
header file tells the machine, "Hey computer, when a programmer instantiates
a Photo object, they should be allowed to access the values of height and
width." In other words, this mechanism allows you to do the following:
Photo myFamily;
cout << myFamily.height; // accessing the value of the object's height myFamily.height = 20; // assigning a value to the object's height Do you see how you can access the height attribute of the Photo
myFamily , as well as assign a new value to this data member?More importantly, do you see the problem? Look at this:
myFamily.height = -12;
Uh oh! Because the height attribute is public,
any programmer using Photo objects can assign any integer value to that member
variable, including ones that don't make sense, such as negative heights.
"Big whoop," you say, "I know that we can make
data members private." And you'd be right (and deserve a gold star for paying
attention). Let's change our class so that arbitrary values can't be assigned
to data members.
Photo.h
class Photo {
public: Photo(); int area(); private: int _height; int _width; }; Ahh, there, now no one can assign values to Photo objects:
myFamily._height = -12;
However, now you've introduced another problem.
By declaring the data members to be
private , you've disabled
all access to the member variables! This means that you can no longer do this:
cout << myFamily._height;
The height attribute is declared to be
private , so there is no direct access to the attribute. Are you
thinking, "I hate C++!"? Don't worry, here's how you can control access to data
members: define member functions we call "getters and setters."Accessors and Mutators, aka Getters and SettersLet us restate the problem above: we do not
want to allow direct access to member variables because invalid values can
be assigned to them, causing the world to end (or, less dramatically, causing
our program to be incorrect). We can declare a data member to be private, but
then the programmer loses the ability to read the value of a data
member as well.
The solution? Let us define two member functions
that we use to manage reading and writing for each data member.
Photo.h
class Photo {
public: Photo(); int area(); int getHeight(); int getWidth(); void setHeight( int h ); void setWidth( int w ); private: int _height; int _width; }; Photo.cpp
Photo::Photo() {
_height = 8; _width = 5; } int Photo::area() { return _height * _width; } int Photo::getHeight() { return _height; } int Photo::getWidth() { return _width; } void Photo::setHeight( int h ) { if( h > 0 ) { _height = h; } } void Photo::setWidth( int w ) { if( w > 0 ) { _width = w; } } If you were to implement the code above, your programs could then do the following:
Photo p;
cout << "Height is " << p.getHeight(); p.setHeight( 20 ); // height is now 20 p.setHeight( -69 ); // height is unchanged Spend time looking at the code in Photo.cpp
above to see what those functions do. Notice how getHeight and getWidth are
very similar. Almost every "getter" function you write will follow this pattern. Ditto for "setter" functions.
In order to understand how this works, you
should realize that member functions have full access to everything
declared inside the class; member functions are not subject to the public/private rules.
Triangle ClassWe've seen triangles before (i.e.,
A2). Now that you have some skills with
classes, write
a Triangle class to represent this "thing" to the computer. What properties do you
need to represent a triangle? Make these properties private to your class. (You
should know why private makes sense; ask if you don't!)
In all functions that modify data members, you should always ensure the
values being set make sense. Also, use a private
helper function wherever one makes sense.
Functions you should include in your class:
main . Be sure your main.cpp
demonstrates all the functions of your class and that they work properly.
Lab Submission
You will submit your solution to this lab with the rest of A7.
Detailed instructions for doing this are posted in Assignment 7.
This lab is due by Tuesday, November 14, 2017 11:59 PM . | |
Last Updated: 11/05/17 21:38
|