What We Will Cover
Continuations
What type of stream must be used to send data from a program to a file?
- input stream
- output stream
- character stream
- binary stream
Homework Questions?
^ top
10.1: Creating and Using Structures
Objectives
At the end of the lesson the student will be able to:
- Code structures containing multiple values
- Use structures in a program
|
^ top
10.1.1: About Structures
- Sometimes you want to keep data together in a group
- Structures provide one way of grouping data
- They are part of the C language and so are included in C++
- Syntax:
struct structName {
dataType1 variable1;
dataType2 variable2;
dataType3 variable3;
...
};
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <iostream>
using namespace std;
struct Product {
int id;
string name;
double price;
};
int main(void) {
Product milk;
milk.id = 100;
milk.name = "Milk";
milk.price = 3.95;
cout << "Data for a milk is:"
<< "\nId: " << milk.id
<< "\nName: " << milk.name
<< "\nPrice: " << milk.price
<< endl;
}
|
- Note that structures are usually placed outside of function definitions
^ top
10.1.2: Member variables and Assignment
- The variables inside a struct are known as member variables
struct Product {
int id;
string name;
double price;
};
In the previous example, note how the dot '.' operator separates the stuct name from the member variable name
milk.id = 100;
milk.name = "Milk";
milk.price = 3.95;
This allows us to access each member variable
You can also assign all the values to a structure at one time:
Product milk = { 100, "Milk", 3.95 };
^ top
10.1.3: Structures and Functions
- Structures can be function arguments
- Either pass-by-value or pass-by-reference
- Structures can be function return types as well
- For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#include <iostream>
using namespace std;
struct Product {
int id;
string name;
double price;
};
Product makeProduct(int id, string name, double price);
void showData(Product prod);
int main(void) {
Product milk;
milk.id = 100;
milk.name = "Milk";
milk.price = 3.95;
Product bread = { 101, "Bread", 2.99 };
Product cheese = makeProduct(102, "Cheese", 4.99);
cout << "Data for milk:";
showData(milk);
cout << "Data for bread:";
showData(bread);
cout << "Data for cheese:";
showData(cheese);
}
Product makeProduct(int id, string name, double price) {
Product p;
p.id = id;
p.name = name;
p.price = price;
return p;
}
void showData(Product prod) {
cout << "\nId: " << prod.id
<< "\nName: " << prod.name
<< "\nPrice: " << prod.price
<< endl << endl;
}
|
^ top
10.1.4: Summary
- Structures contains multiple values of possibly different types
- Structure definitions are usually placed outside of any function definition
- Member variables can be used just as any other variable of the same type
- Structures can be arguments in function calls
- Structures can be the type of a value returned by a function
- Structures can be initialized when declared
- Structures can contain member variables that are also structures
Check Yourself
- What is a structure? Member variable?
- How many member variables can a structure contain?
- How do you access a member variable of a structure?
^ top
Exercise 10.1
In this exercise we look at how to use a structure.
Specifications
- Save the following starter code as
rectstruct.cpp.
- Add member variables
length and width in the Rectangle struct.
- Write a
showData() function that displays the data inside the structure.
- Write a
main() function that creates one or more Rectangle structures and passes them to the showData() function.
- Submit your program code as the solution for this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#include <iostream>
using namespace std;
struct Rectangle {
// Put member variables here
};
void showData(Rectangle rect);
int main() {
// place statements to create a struct here
return 0;
}
// Define showData() function here
|
^ top
10.2: Introduction to Classes and Objects
Objectives
At the end of the lesson the student will be able to:
- Describe classes, objects, member functions and member variables
- Declare a class and use it to create an object
- Call a function of an object to perform a task
|
^ top
10.2.1: About Classes and Objects
- Object: something material that you can perceive using your senses
- Everywhere you look in the real world you see objects
- People
- Animals
- Plants
- Buildings
- Cars
- Humans think in terms of objects
- Humans learn about objects by studying their attributes and behaviors
- Attributes are things like: size, shape, color and weight
- Behaviors are what an object does, like:
- A person walks, runs, crawls, talks and sits
- A plant grows and wilts
- A car accelerates, brakes and turns
- Object-oriented programming (OOP) grew out of using software to model complex systems in the real world
- Spread of disease in humans, animals and plants
- Design of buildings or other large objects
- Design of cars
- Ecosystem simulation
- Network routing
- Weather prediction
- Object-oriented design (OOD) models software like the way people study objects in the real world
- It takes advantage of relationships where objects of a certain class, like buildings, have similar attributes and behaviors
- OOD provides a natural and intuitive way to view software design by describing their attributes and behaviors
^ top
10.2.2: Modeling Objects in Software
- Let's use a simple analogy to help us understand classes and objects
- Suppose you want to build a product
- You design the product and produce a plan (blueprint) for making the product
- These blueprints describe all the attributes of the product, like:
- If the product has moving parts or other functions, you describe the functionality of the product in the blueprints as well
- For instance, it the product is an iPod, you would describe functions for:
- Playing music
- Adjusting the volume
- We can use this analogy to introduce some of the OOP concepts
- The blueprint of a product is like a class in OOP
- We create a description of the object by writing a class
- A class describes the attributes of an object using member variables
- With class
IPod, we might have member variables such as:
double length: the length of the device
double width: the width of the device
int volume: the volume setting of the music
- Member variables are said to hold the state (configuration) of an object
- A class also describes the behavior of an object using member functions
- For example, class
IPod might have a function like:
void setVolume(int newVolume): adjust the music volume
void playSong(string name): select the song to play
Making Objects from Designs
- A design (blueprint) of a product is not a product
- Before you can use an iPod, a factory must build it
- The factory uses the blueprints to make the device
- Similarly, you must create an object of a class before you can use an object
- After an object is built, you can control the behavior of the object
- For instance, on an iPod, you adjust the controls to control its behavior
^ top
10.2.3: Declaring a Class with a Function
- Let us continue our analogy by writing a class for an iPod
- We will keep it simple since we only want a simple model
- The first thing to note is that classes are like structures
- However, classes have some additional features
- For instance, in addition to containing member variables, they can have member functions as well
- All classes start with a statement declaring the class
- For our first iPod class, we include a function to play a song
Class IPod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <iostream>
using namespace std;
class IPod {
public:
void playSong(string name);
};
// Using the IPod class
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
IPod yourIPod;
yourIPod.playSong("Yellow");
return 0;
}
// Member function definition
void IPod::playSong(string name) {
cout << "Playing song: " << name << endl;
}
|
- The class declaration begins with:
class IPod {
Every class declaration includes the keyword class followed by its name
In addition, every class' body is enclosed in a pair of curly braces
The keyword public is an access specifier or visibility modifier
This indicates that everything following is "available to the public"
More specifically, everything following can be accessed from outside the class
Member Function Declaration (Prototype)
- The function declaration is:
void playSong(string name);
Because the function declaration comes after the keyword public, it is "available to the public"
The function declaration includes the return type, name and a semicolon
This is the same syntax we have used for functions declarations before
The only difference is that the function declaration is contained inside the curly braces of the class
Member Function Definition (Body)
- The definition of the function is outside the class:
void IPod::playSong(string name) {
cout << "Playing song: " << name << endl;
}
This is like previous function definitions except for: IPod::
We need to use IPod:: to tell the compiler that the declaration for the function is inside the class IPod
^ top
10.2.4: Creating an Object and Calling a Function
- Now we would like to use our
IPod class in an application
- Every application must have one
main() function
- Note that our code has a
main() function like other programs be have built so far
// Using the IPod class
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
IPod yourIPod;
yourIPod.playSong("Yellow");
return 0;
}
However, the main() function is not part of the class
You can tell that main() is not part of the class because it is:
- Not inside the class
IPod
- Does not have
IPod:: in front of the name
Creating an Object
- To use a class, you usually start by creating an object of the class
- Also known as creating an instance of the class
- In C++ you can create an instance of a class by:
- Writing the class name
- Followed by a variable name to store the object
- For example:
IPod myIPod;
The variable name is known as the object name
Calling a Member Function (Sending a Message)
- In our application, we want to call the
playSong() function
- To call a function, you use the object name, a dot (period), the function name and a set of parenthesis
myIPod.playSong("It's My Life");
Sometimes designers refer to these member function calls as, "sending a message"
When we call the function, we are sending a message to myIPod to "play a song"
Note that we need an object name in front of the function name to say which object we want to use
myIPod.playSong("It's My Life");
yourIPod.playSong("Yellow");
In the first function call, we are selecting a song for myIPod
In the second function call, we are selecting a song for yourIPod
^ top
10.2.5: Declaring Member Variables
- Classes usually have one or more functions that change their attributes
- Instance (member) variables store the attributes of an object
- Each object maintains its own copy of these variables
- To continue our analogy, we will update our
IPod class with an instance variable
Class IPod with an Instance Variable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#include <iostream>
using namespace std;
class IPod {
public:
void playSong(string name);
string getSong();
private:
string song;
};
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
cout << "I am listening to the song: "
<< myIPod.getSong() << endl;
return 0;
}
// Member function definitions
void IPod::playSong(string name) {
song = name;
cout << "Playing song: " << song << endl;
}
string IPod::getSong() {
return song;
}
|
An Instance Variable
- The instance variable is declared after the keyword
private:
private:
string song;
Instance variables are declared inside a class declaration but outside the bodies of the class's functions
The keyword private means that the instance variable is not accessible outside the class
Most instance variables are declared private
- Declaring an instance variable as private is known as data hiding
- We will discuss why this is done later
However, it is important to note that if the variable were declared in the public area, we could access it like we accessed variables in a struct
Instance Functions
- To make use of a private instance variable, we use a public function that can access the variable
- In our class, we have two such instance functions
- Function
playSong() will set or change the song of an IPod object
void IPod::playSong(string name) {
song = name;
cout << "Playing song: " << song << endl;
}
Function getSong() will return the song of an IPod object
string IPod::getSong() {
return song;
}
How can we tell that these functions are part of class IPod?
Testing Class IPod
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
cout << "I am listening to the song: "
<< myIPod.getSong() << endl;
return 0;
}
Our main() function instantiates an IPod object:
The myIPod.playSong() function is called to play the song
The myIPod.getSong() function is called to get the current song of myIPod
^ top
10.2.6: Summary
- In object-oriented programming, objects are modeled after real-world objects
- Object-oriented design (OOD) takes advantage of relationships where objects of a certain class, like iPods, have similar attributes and behaviors
- In object-oriented programming (OOP), we create a "blueprint" of an object by writing a class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#include <iostream>
using namespace std;
class IPod {
public:
void playSong(string name);
string getSong();
private:
string song;
};
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
cout << "I am listening to the song: "
<< myIPod.getSong() << endl;
return 0;
}
// Member function definitions
void IPod::playSong(string name) {
song = name;
cout << "Playing song: " << song << endl;
}
string IPod::getSong() {
return song;
}
|
- Just like a blueprint is not an iPod, a class is not an object
- Before we can use an object, we must create (instantiate) an object from the class
- There are two steps to creating an object:
- Writing the class name
- Followed by a variable name to store the object
- For example:
IPod myIPod;
One you create an object, you can "pass it a message" by calling its functions
myIPod.playSong("It's My Life");
Classes usually have functions that change the attributes that belong to an object of the class
Instance variables store the attributes of an object
Each object maintains its own copy of these variables in the computer's memory
Instance variables are declared inside a class declaration but outside the bodies of the class's functions
Most instance variables are declared with the access modifier private
private:
string song;
Since the private modifier prevents access outside an object of the class, you must use the instance functions of the class to access an instance variable
We will discuss why this is done in the next section
Check Yourself
- What is a class?
- What is an object?
- What is the difference between a class and an object?
- What is the syntax for declaring a class?
- How do you create an object from a class?
- How do you pass a message from one object to another?
- How do you call an object's functions?
- How does an object maintain state (remember its current settings)?
^ top
Exercise 10.2
One problem that people have when first using objects and classes is to understand the flow of control. In this exercise we trace the execution of a program that uses a class.
Specifications
- Create a file named trace.txt
- In the trace.txt file, list the number of each line for the following program in the order the lines are processed.
Do not bother to list lines containing just a closing curly brace (}) of a function definition.
- Submit the trace.txt file as the solution to this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#include <iostream>
using namespace std;
class IPod {
public:
void playSong(string name);
string getSong();
private:
string song;
};
int main() {
IPod myIPod;
myIPod.playSong("It's My Life");
cout << "I am listening to the song: "
<< myIPod.getSong() << endl;
return 0;
}
// Member function definitions
void IPod::playSong(string name) {
song = name;
cout << "Playing song: " << song << endl;
}
string IPod::getSong() {
return song;
}
|
^ top
10.3: Coding Classes to Create Objects
Objectives
At the end of the lesson the student will be able to:
- Describe the concept of encapsulation and data hiding
- Design classes that create objects
- Code member variables and member functions
|
^ top
10.3.1: Encapsulation and Data Hiding
- As programs become larger, you need to change the way you work on them
- Large programs usually have teams of people who work on them
- One or two software engineers may work on the user interface
- Another two or three may work on the logic of the application and various features
- Another may work on data storage and retrieval
- When many programmers work together, you need to take special care to protect the data of the application
- For instance, two or three people may work on code to retrieve data from a database, make some computation and then display it on a screen
- Unless the programmers take care, they may accidentally store incorrect values in the variables
- These incorrect values show up as "strange bugs" that creep into the program
- Object-oriented programs provide two important ways to help protect and control program data:
- Encapsulation
- Data hiding
Encapsulation
Data Hiding
^ top
10.3.2: Defining Classes
- Let us look at how to define classes using encapsulation and data hiding
- Basic Syntax
class className {
permissionLabel1:
member1;
...
permissionLabel2:
member2;
...
...
};
For Example
- The following is the code for a class named
Product
- Class declarations typically contain two general sections:
public functions
private variables and functions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#include <iostream>
using namespace std;
class Product {
public:
// Member functions
string getName();
double getPrice();
void setName(string newName);
void setPrice(double newPrice);
void show();
private:
// Member variables
string name;
double price;
};
string Product::getName() {
return name;
}
double Product::getPrice() {
return price;
}
void Product::setName(string newName) {
if (newName.length() == 0) {
name = "Unknown";
} else {
name = newName;
}
}
void Product::setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
void Product::show() {
cout << name << " has a price of $"
<< price << endl;
}
// For testing
int main() {
Product milk;
milk.setName("Milk");
milk.setPrice(3.95);
Product bread;
bread.setName("Bread");
bread.setPrice(2.99);
milk.show();
bread.show();
return 0;
}
|
- Note that there are two sections to the code for the class
- The class is declared between the curly braces following the class name
- Class member functions are defined after the class declaration
- To show that the function belongs to the class, you use the class name and the scope resolution operator "::"
void Product::setName(string newName) {
//...
}
Private Members and Data Hiding
- Note the keywords
private and public
- Referred to as permission labels, access specifiers or visibility modifiers
private: can only be accessed by member functions of this class
public: can be accessed by any function
- Setting
private accessibility for all data is a good design practice
- This protects data by controlling access only through the
public functions
- This allows a programmer to change how data is stored and operated on at some future time without affecting code outside the class
- As long as the header for the public function does not change
Programming Style: Class Naming Conventions
- Use nouns to name classes -- they represent objects
- Start class names with a capital letter
- Capital letter differentiates classes from functions and variables
^ top
10.3.3: Coding Member Variables
- We now look at each section in more detail
- Member variables store the attributes (data) of an object
- Each object has its own copy of these variables
- Syntax for declaring member variables:
type variableName
For now, use the private access modifier for all member variables
The type can be any primitive type or a class name
Member variables work just like variables you have used previously
The only difference is they are encapsulated by the class
Examples
private:
string name;
double price;
^ top
10.3.4: Coding Member Functions
- Member functions define the operations that can occur on an object
- Performing these operations is sometimes referred to as passing messages
- Thus, objects use member functions to pass messages to each other
- The syntax for declaring member functions is that same as other functions:
returnType functionName(parameter list);
For example:
public:
string getName();
double getPrice();
void setName(string newName);
void setPrice(double newPrice);
void show();
The only difference is that the declarations are encapsulated by the class
The syntax for defining functions declared inside a class:
returnType ClassName::functionName(paramters) {
// statements of the function
}
For example:
void Product::setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
In general, you should declare most class functions public
However, if you want to prevent a function from being used outside a class, declare it private
These public functions are known as the object's interface
Also, you can overload member functions just like you can overload regular functions
Function Naming Conventions
- As mentioned before, use verbs for function names
- Appropriate since they perform an action
- Also start function names with a lower case letter
- Not required by syntax, but is a convention that professional programmers follow
Set Functions
- When variables are declared
private, you may still need to modify them
- You use
public functions to modify private variables
- Called set functions (a.k.a. mutator functions)
- A common naming convention is to use the name of the variable with the word set prepended
- Such functions often verify the value is correct before setting it
- For example, since prices should not be a negative value:
void Product::setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
Get Functions
- Also, you often need to know the value of
private variables
- You use
public functions to get the value of private data
- Called get functions (a.k.a. accessor functions)
- A common naming convention is to use the name of the variable with the word get prepended
- For example:
string Product::getName() {
return name;
}
^ top
10.3.5: Creating Objects From Classes
- After defining a class, we create one or more objects
- The syntax for creating an object of a class:
ClassName objectName;
For Example
- We can code a main function to create an object of our class
- When the
new operator is used, memory space is allocated for the object variables
int main() {
Product milk;
When the object is created, memory is allocated for the class variables
private:
string name;
double price;
However, the memory is uninitialized
Thus we need to assign the memory values:
milk.setName("Milk");
milk.setPrice(3.95);
Functions setName() and setPrice() are called with the appropriate arguments
Function setName() assigns the member variable name the parameter newName
Function setPrice() assigns the member variable price the parameter value of newPrice
One object, an instance of the class, has now been created and initialized
You can create as many objects as you need for your program
Once created, your program can access each object using its public functions:
cout << milk.getName() << endl;
cout << milk.getPrice() << endl;
milk.show();
^ top
10.3.6: Summary
- OOP addresses the problem of data protection through encapsulation and data hiding
- Encapsulation and data hiding allow you to change the inner workings of a class without affecting other classes
- The ability to change portions of a program without affecting other parts becomes more important as programs grow larger
- Member variables store the data of an object
- You declare and use member variables like other variables except they are encapsulated inside a class
- Member functions are the operations that can occur on the object
- Access modifiers control access to variables and functions
private: can only be accessed by member functions of this class
public: can be accessed any function
- To implement data hiding, you declare variables in the
private section of a class
- For this course, use
private for all variables and public for most functions
- Functions in the
public section of a class provide the methods for working with the class
- Use "set" functions to control setting of new values for
private variables
- Use "get" functions to return values of
private variables
- Classes are like a template or blueprint for creating objects
- Objects are constructed from these classes
- You create an instance of a class (an object) using code like the following:
Product milk;
milk.setName("Milk");
milk.setPrice(3.95);
Check Yourself
- What is meant by the terms "encapsulation" and "data hiding"?
- What is the syntax for coding a class?
- How do you code member variables?
- What are the differences between local variables and member variables?
- How do you code member functions?
- What two member functions are coded if you need to both change and get the value of an member variable?
^ top
Exercise 10.3
In this exercise we write our first class.
Specifications
- Save the following starter code as
Rectangle.cpp.
- Write suitable declarations for member variables
length and width.
- Code set and get functions for both of the variables following the recommended naming conventions.
- Use the name of the variable with the word set prepended
- Use the name of the variable with the word get prepended
- Write a
show() function that displays the length and width of the object.
- Write a
main function that instantiates two or more Rectangle objects and calls their show() functions.
- Submit your program code as the solution to this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <iostream>
using namespace std;
class Rectangle {
public:
// Put member function prototypes here
private:
// Put member variables here
};
// Put Rectangle function definitions here
int main() {
// place statements to instantiate objects here
return 0;
}
|
^ top
10.4: Improving the Class
Objectives
At the end of the lesson the student will be able to:
- Write inline functions
- Discuss the purpose of a constructor
- Write code to declare, define and make use of a constructor
- Code no-arg constructor calls correctly
- Describe how to prevent "local shadowing"
|
^ top
10.4.1: Inline Functions
- Inside a class, you can define a member function when it is declared
- For example:
class Product {
public:
string getName() { return name; }
double getPrice() { return price; }
// ... more code here
These are known as in-line functions
It is common practice to code such short function bodies in the class definition section
The general rule is to code functions in-line if they fit on one line
This lets you avoid the extra coding of defining the functions outside the class such as these:
// No longer needed since we used inline functions
//string Product::getName() {
// return name;
//}
//double Product::getPrice() {
// return price;
//}
^ top
10.4.2: Introducing Constructors
- Often you want to initialize some or all of the member variables of an object when you create the object
- For example, rather than this:
int main() {
Product milk;
milk.setName("Milk");
milk.setPrice(3.95);
// ... more code here
You would like to code something like this:
int main() {
Product milk("Milk", 3.95);
// ... more code here
Also, there are times when you would like to assign a default value to some or all of the member variables
C++ provides a special function to let you do all of this known as a constructor
A constructor is a member function that is automatically called when an object of a class is created
The purpose of the constructor is to initialize the values of the member variables
The programmer still decides which member variables are assigned a value by coding assignment statements inside the constructor
The following program shows a class with constructors defined
Product Class with Constructors Added
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <iostream>
using namespace std;
class Product {
public:
// Constructors
Product();
Product(string newName);
Product(string newName, double newPrice);
// Member functions
string getName() { return name; }
double getPrice() { return price; }
void setName(string newName);
void setPrice(double newPrice);
void show();
private:
// Member variables
string name;
double price;
};
// no-parameter constructor
Product::Product() {
name = "Unknown";
price = 0.0;
}
Product::Product(String newName) {
setName(newName);
price = 0.0;
}
Product::Product(string newName, double newPrice) {
setName(newName);
setPrice(newPrice);
}
void Product::setName(string newName) {
if (newName.length() == 0) {
name = "Unknown";
} else {
name = newName;
}
}
void Product::setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
void Product::show() {
cout << name << " has a price of $"
<< price << endl;
}
// For testing
int main() {
Product milk("Milk", 3.95);
Product bread("Bread", 2.99);
milk.show();
bread.show();
return 0;
}
|
^ top
10.4.3: Coding Constructors
- Constructors are a special type of function coded for a class and thus are coded like a function
- However, there are slight syntax differences
- Constructor declarations (prototypes) are placed inside the class declaration like other member functions
- Constructor definitions are usually placed outside the class declaration
- Unless they are short "one-liners"
- In which case they are defined inline
- Syntax for declaring constructors:
ClassName(parameterList);
You place constructors in the public section of the class declaration
- Your program calls the constructor when creating objects
Constructors must use the same name and capitalization as the class name
public:
// Constructors
Product();
Product(string newName, double newPrice);
Constructors can have zero or more parameters, just like functions
Thus you can have many constructors in a class, but each must have a different signature
The name of the constructor combined with the parameter list form its signature
Example: Constructor Definition with no Parameters
- If you do not want to accept arguments for member variables, code a constructor with no parameters:
Product::Product() {
name = "Unknown";
price = 0.0;
}
Note that constructors with no parameters are called no-arg constructors
Example: Constructor Definition with two Parameters
- If you want to accept arguments for all member variables, code a constructor with parameters for each variable:
Product::Product(string newName, double newPrice) {
setName(newName);
setPrice(newPrice);
}
Note the use of the functions setName() and setPrice()
This makes certain that the values assigned to the object pass the tests for correctness defined in these functions
Example: Constructor Definition with one Parameter
- If you want to accept only some arguments, code a constructor appropriately:
Product::Product(string newName) {
setName(newName);
price = 0.0;
}
Default Constructors
- If the programmer does not define a constructor, then the compiler supplies an empty "no-parameter" one like the following:
public:
Product() {}
However, if the programmer defines any constructor, the compiler does not supply a default constructor
^ top
10.4.4: Creating Objects from Classes that Define Constructors
- When you create an object with a defined constructor, you included the arguments inside a set of parenthesis
- The syntax is:
ClassName objectName(argumentList);
For example:
Product milk("Milk", 3.95);
You must call the constructor with the correct sequence and type of arguments, just like other functions
Deciding Which Constructor to Call
- If the class has more than one constructor, the constructor matching the argument list is used
- For example, if our class has the following three constructors:
Product();
Product(string newName);
Product(string newName, double newPrice);
Which constructor is called when the following objects are created?
Product milk;
Product bread("Bread");
Product cheese("Cheddar", 6.75);
Avoiding the No-Parameter Trap
- Notice the difference in the number of parenthesis between the first object created and the others
- First statement calls the no-parameter constructor
Product milk;
Other statements call a different constructor
It is an error to call the no-parameter constructor like this:
Product milk2(); // wrong
However, the compiler will not catch the error!
It is legal syntax to declare a function like milk2() with no parameters
Trying to use milk2() will cause an error
milk2.getName(); // causes error
^ top
10.4.5: Local Variables, Parameters and Shadowing
- Local variables and parameters with same name as a class variable hide the class variable
- Any use of the variable's name will refer to the local variable or parameter
- This is the source of many an elusive bug
- Thus, you should not use the same name for a local variable or parameter and a class variable
- Remember that a parameter is like a local variable but initialized in a special way
- Thus you should use a different name for a parameter and a class variable
- Which lines contain local shadowing in the following program?
Example of Shadowing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include <iostream>
using namespace std;
class MyRectangle {
public:
MyRectangle(double length, double width);
void showData();
private:
double length;
double width;
};
MyRectangle::MyRectangle(double length, double width) {
length = length;
width = width;
}
void MyRectangle::showData() {
cout << "length: " << length
<< "\nwidth: " << width
<< endl;
}
// For testing
int main() {
MyRectangle rec(3.0, 5.0);
rec.showData();
return 0;
}
|
^ top
10.4.6: Summary
- When get functions are short, you can code them as inline functions
- For example, the same function coded inline inside the class:
public:
string getName() { return name; }
Constructors are called whenever an object is created from a class
If the class has more than one constructor, the constructor matching the argument list is used
For example, if our class has the following three constructors:
Product();
Product(string newName);
Product(string newName, double newPrice);
The following call the constructors in order
Product milk;
Product bread("Bread");
Product cheese("Cheddar", 6.75);
You must use care when calling a no-parameter constructor
Product milk2(); // wrong (but compiles)
Product milk3; // right
Local variables and parameters with same name as a class variable hide the class variable
You should not use the same name for a local variable and a class variable
Check Yourself
- What is an in-line function?
- What is the purpose of a constructor?
- How do you code a constructor for a class?
- What is the difference in syntax between coding a constructor and coding a regular function?
- How many constructors can you define for each class definition?
- When does a compiler automatically include a constructor?
- How does the syntax for calling a no-parameter constructor differ from calling constructors that have parameters? Why?
- What is meant by the term "local shadowing"?
- How do you avoid "local shadowing"?
^ top
Exercise 10.4
In this exercise we explore local shadowing.
Specifications
- Save the following code as
Shadowing.cpp.
- The program has a problem that prevents it from running correctly. Fix the program so that it compiles and runs correctly.
- Submit your corrected program as the solution to this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include <iostream>
using namespace std;
class MyRectangle {
public:
MyRectangle(double length, double width);
void showData();
private:
double length;
double width;
};
MyRectangle::MyRectangle(double length, double width) {
length = length;
width = width;
}
void MyRectangle::showData() {
cout << "length: " << length
<< "\nwidth: " << width
<< endl;
}
// For testing
int main() {
MyRectangle rec(3.0, 5.0);
rec.showData();
return 0;
}
|
^ top
Wrap Up
Reminders
Due Next: A9: Calculate Your Grade (4/26/07)
Exercise 9 and CodeLab Lesson 9 (4/26/07)
A10: Getting Classy (5/3/07)
Exercise 10 (5/3/07)
- When class is over, please shut down your computer
- You may complete unfinished exercises at the end of the class or at any time before the next class.
^ top
Home
| Blackboard
| Announcements
| Day Schedule
| Eve Schedule
Course info
| Help
| FAQ's
| HowTo's
| Links
Last Updated: April 19 2007 @14:07:37
|