Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct....

34
Chapter 9 Defining New Types

Transcript of Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct....

Page 1: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Chapter 9

Defining New Types

Page 2: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Objectives

• Explore the use of member functions when creating a struct.

• Introduce some of the concepts behind object-oriented programming.

• Introduce class definitions and the private and public labels.

• Implement some simple constructors.

Page 3: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

C++

I invented the term Object-Oriented, and I can tell you I did not have C++ in mind.

– Alan Kay

The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

– Joe Armstrong

Page 4: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

C++ Types

• There are two kinds of classes in C++.– Built-in types: char, int, bool, double, etc.– Class types

• These can be imported from standard libraries using #include.

• We can also create our own class types.

• So far in the course we have been focused on using the built-in and standard library class types.

• Now we switch to defining our own class types.

Page 5: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Student_info Revisited

• In our previous Student_info type we had code that worked but had a few challenges.

• The code made assumptions about how it was used.– A Student_info object is created without any data in it

but most of the functions assume that data is present.– All manipulation of the data must be done directly – it is

necessary to understand the type in order to use it.

• We would like to hide the implementation details from someone using the code.

• We would like to protect the data from accidental manipulation.

Page 6: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Student_info Structure

struct Student_info {

std::string name;

double midterm, final;

std::vector<double> homework;

}• We want to restrict access to the data so that users of

this code must go through functions we can control.• That way we can protect the data from unwarranted

assumptions, prevent accidental manipulation, and hide the implementation details from the user.

• These functions will be the interface to our new type.

Page 7: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Student_info Structure

• We want to do things in a general way and minimize the restrictions we put on the users of our code.

• This is why we have the lines std::string and std::vector. The user of our code may not want to be locked into a using command.

Page 8: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Member Functions

• We can add functions to our Student_info structure.struct Student_info {

std::string name;

double midterm, final;

std::vector<double> homework;

std::istream& read(std::istream&);

double grade() const;

}• The const declaration on grade is a promise that this

function will not change the data in the record.

Page 9: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Member Functions

• When we create a Student_info object we can access these functions in the same manner we did for the library classes.

Student_info s;

s.read(cin);

cout << s.grade();• We are essentially sending a message to the

object, telling it what to do.• Our object now has data and behaviors.

Page 10: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Defining Member Functions

• The functions are similar to the ones we had in our previous implementation.

istream& Student_info::read(istream& in)

{

in >> name >> midterm >> final;

read_hw(in, homework);

return in;

}• As before we will put the definitions for the member

functions in a C++ file (.C, .cc, .cp, .cpp) and the structure declaration in a header file (.h).

Page 11: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Defining Member Functions

• There are a few differences in the new read function.

• The name is now Student_info::read. This indicates that it belongs to the Student_info structure.

• Because the function belongs to the structure we no longer need to pass a parameter to a Student_info structure.– The call was read(cin, s) and is now s.read(cin). In

either case we know which object we are reading.

• Since the function call belongs to a particular object, we can access the data elements directly (midterm instead of s.midterm).

Page 12: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

grade Function

• We have a little problem since our grade function calls another function (with the same name but different signature) that is not part of our structure.

• Since we are inside a structure the compiler will assume we mean the grade function that also inside the structure.

• We will get an error because we do not have the right number of parameters.

• We need a way to tell the compiler to look outside the structure.

Page 13: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

grade Function

double Student_info::grade() const

{

return ::grade(midterm, final, homework);

}• The ::grade forces the compiler to look for a grade function

that is not part of any structure or class.• Notice the const declaration. This means the function is a const member function and will not change the data in the object.

• const functions can be used with constant objects where ordinary function cannot.

• We often pass a parameter to a function as a const reference, so this is important.

Page 14: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Which Functions Should be Members?

• The question of which functions should be members is worth careful consideration.

• In some cases the answer is clear-cut.– Functions that modify data should be members

functions.

• What about compare? It doesn’t modify anything.

• Passing compare to sort would be difficult as a member function.

• We will leave compare as a global function.

Page 15: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Protection

• We have modified our code so that it is not necessary to modify the data directly.

• We want to put in protections so that it is impossible to modify the data except through member functions.

• We will label the attributes of our structure.– public attributes will be directly accessible outside the

structure.– private attributes can only be accessed through public

functions.

• We will also switch from struct to class.

Page 16: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Protection

class Student_info {

public:

std::istream& read(std::istream&);

double grade() const;

private:

std::string n;

double midterm, final;

std::vector<double> homework;

};

Page 17: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

struct VS class

• The only difference between a struct and a class is the default classification.

• With a struct the default classification for unlabeled members is public.

• With a class the default classification for unlabeled members is private.

• It is traditional to use struct for simple types whose data we want to expose.

• We use class for more complex types whose data we want to hide.

Page 18: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

C++ VS Python

• Classes in C++ and Python are similar but there are some differences.

• In C++ you must list all the data members in the class definition.

• In C++ you get to pick which data members and functions are public and which are private.

Page 19: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Accessor Functions

• We need to add an accessor function so that the user of our class can use the students name.

class Student_info {

public:

std::string name() const { return n; }

std::istream& read(std::istream&);

double grade() const;

private:

std::string n;

double midterm, final;

std::vector<double> homework;

};

Page 20: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Accessor Functions

• Notice that the name function is so simple that it really doesn’t make sense to have a declaration here and a definition somewhere else.

• Including the definition here also allows the compiler to implement this as an inline function.

• With this type of function the cost of a function call is avoided by replacing the call to the function with its code.

• It may run faster.

Page 21: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

compare Function

• We can now write the compare function.bool compare(const Student_info& x, const Student_info& y)

{

return x.name() < y.name();

}

• This is very similar to the compare function we had before.

• Now we use the accessor function to get the names.

Page 22: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Testing for Empty

• We also need a member function to test to see if the homework vector is empty.

• Users will no longer be able to access the vector directly to check for this, so we need to provide a function to do it.

class Student_info {

public:

bool valid() const { return !homework.empty(); }

// the rest is the same as before

Page 23: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors

• It would be nice to have a function that would automatically be called when we create a Student_info object.

• This type of function is called a constructor.• They are used so that we never need to worry

about an uninitialized object.• There is no way to call a constructor explicitly.

It is called as a side effect of creating an object.

Page 24: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors

• If we do not create our own constructor, one will be created for us that uses default values.

• In the case of Student_info we will get the following.– n defaults to the empty string.

• Since this is a string object the constructor for the string class is called.

– homework defaults to the empty vector.• Since this is a vector object the constructor for the vector class is

called.

– midterm and final default to undefined. They could contain any garbage that happened to be in the memory location they are assigned.

• If we mistakenly use an uninitialized Student_info object, the results are unpredictable.

Page 25: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors

• We can have multiple constructors as long as they have different signatures.

• Since the names are the same this means having different parameter lists.

• Ideas for constructors:– Initialize everything to 0.– Accept parameters for values to initialize the

variables.– Accept a parameter to an istream and read the

initial values.

Page 26: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors

• We will do two of these: initialize to 0 and read from an istream.

• Calling these constructors would look like the following.

Student_info s1;

Student_info s2(cin);• Constructors cannot have a return type.

Page 27: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors

• Our class now looks like the following.class Student_info {

public:

Student_info();

Student_info(std::istream&);

// the rest is the same as before• Note that the name of the constructor(s) is the

same as the name of the class.• Notice there is no return type (not even void).

Page 28: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Default Constructor

• The default constructor is the one that will be called if we create an object with no parameters.

Student_info::Student_info(): midterm(0), final(0) { }• Notice the new syntax.• Between : and { is a series of constructor initializers.• It tells the compiler to initialize the listed variables to

the specified values.– midterm = 0– final = 0

Page 29: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructor Initializers

• With constructor initializers, the following steps are performed.

• Memory is allocated for all the variables in the class

• The initial values are assigned according to the constructor initializers.

• The function body is executed.• In this case the initialization is all we wanted

to do so the body of the function is empty.

Page 30: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Constructors with Arguments

• The other constructor does the same thing as our read function, so all we need to do is call read.

Student_info::Student_info(istream& is) { read(is); }

Page 31: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Using the Student_info class

int main()

{

vector<Student_info> students;

Student_info record;

string::size_type maxlen = 0;

while (record.read(cin)) {

maxlen = max(maxlen, record.name().size());

students.push_back(record);

}

sort(students.begin(), students.end(), compare);

Page 32: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Using the Student_info class

for (vector<Student_info>::size_type i = 0;

i != students.size(); ++i) {

cout << students[i].name()

<< string(maxlen + 1 - students[i].name().size(), ' ');

try {

double final_grade = students[i].grade();

streamsize prec = cout.precision();

cout << setprecision(3) << final_grade

<< setprecision(prec) << endl;

} catch (domain_error e) {

cout << e.what() << endl;

}

}

return 0;

}

Page 33: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Using Student_info class

• The changes here are in the calls to name, read and grade.

• record.read(cin) replaces read(cin, record).• record.name().size() replaces record.name.size().• students[i].name() replaces students[i].name.• students[i].grade replaces grade(students[i]).

Page 34: Chapter 9 Defining New Types. Objectives Explore the use of member functions when creating a struct. Introduce some of the concepts behind object-oriented.

Homework Chapter 9 (page 168)

• Total 40 pts possible.– 9-0– 9-1 (email, 15 pts)– 9-2 (paper, 10 pts)– 9-3 (email, 15 pts)– 9-4 (email, 15 pts)– 9-7 (paper, 5 pts)