While C++ provides a number of basic data types (eg. char, int, long, float, double, etc…) that are often sufficient for solving relatively simple problems, it can be difficult to solve complex problems using just these types. One of C++’s more useful features is the ability to define your own data types that better correspond to the problem being worked upon. You have already seen how enumerated types and structs can be used to create your own custom data types.
Here is an example of a struct used to hold a date:
Enumerated types and structs represent the traditional non-object-oriented programming world, as they can only hold data. If you want to initialize or manipulate this data, you either have to do so directly, or write functions that take a DateStruct as a parameter:
10 | void SetDate(DateStruct &sDate, int nMonth, int nDay, int Year) |
12 | sDate.nMonth = nMonth; |
18 | SetDate(sToday, 10, 14, 2020); |
In the world of object-oriented programming, we often want our types to not only hold data, but provide functions that work with the data as well. In C++, this is done via the
class keyword. Using the class keyword defines a new user-defined type called a class.
Classes
In C++, classes are very much like structs, except that classes provide much more power and flexibility. In fact, the following struct and class are effectively identical:
Note that the only difference is the
public: keyword in the class. We will discuss it’s function in the next lesson.
Just like a struct definition, a class definition does not declare any memory. It only defines what the class looks like. In order to use a class, a variable of that class type must be declared:
In C++, when we declare a variable of a class, we call it
instantiating the class. The variable itself is called an
instance of the class. A variable of a class type is also called an
object.
Member Functions
In addition to holding data, classes can also contain functions! Here is our Date class with a function to set the date:
08 | void SetDate( int nMonth, int nDay, int nYear) |
Just like member variables of a struct or class, member functions of a class are accessed using the member selector operator (.):
2 | cToday.SetDate(10, 14, 2020); |
Note that in the original struct version of SetDate(), we needed to pass the struct itself to the SetDate() function as the first parameter. Otherwise, SetDate() wouldn’t know what DateStruct we wanted to work on.
However, in our class version of SetDate(), we do not need to pass cToday to SetDate()! Because SetDate() is being called on cToday, the member variables in SetDate() will refer to the member variables of cToday! Thus, inside function SetDate(),
m_nDay
is actually referring to
cToday.m_nDay
. If we called cTomorrow.SetDate(),
m_nDay
inside of SetDate() would refer to
cTomorrow.m_nDay
.
Using the “m_” prefix for member variables helps distinguish member variables from function parameters or local variables inside member functions. This is useful for several reasons. First, when we see an assignment to a variable with the “m_” prefix, we know that we are changing the state of the class. Second, unlike function parameters or local variables, which are declared within the function, member variables are declared in the class definition. Consequently, if we want to know how a variable with the “m_” prefix is declared, we know that we should look in the class definition instead of within the function.
By convention, class names should begin with an upper case letter.
Here’s another example of a class:
10 | void SetInfo( char *strName, int nID, double dWage) |
12 | strncpy (m_strName, strName, 25); |
21 | cout << "Name: " << m_strName << " Id: " << |
22 | m_nID << " Wage: $" << m_dWage << endl; |
30 | cAlex.SetInfo( "Alex" , 1, 25.00); |
33 | cJoe.SetInfo( "Joe" , 2, 22.25); |
This produces the output:
Name: Alex Id: 1 Wage: $25
Name: Joe Id: 2 Wage: $22.25
Warning: One of the most common C++ mistakes is to forget to end all class (and struct) declarations with a semicolon. This can cause the compiler to report all sorts of weird, seemingly-unrelated errors!
No comments:
Post a Comment