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:
struct DateStruct
{
int nMonth;
int nDay;
int nYear;
};
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:
// Declare a DateStruct variable
DateStruct sToday;
// Initialize it manually
sToday.nMonth = 10;
sToday.nDay = 14;
sToday.nYear = 2020;
// Here is a function to initialize a date
void SetDate(DateStruct &sDate, int nMonth, int nDay, int Year)
{
sDate.nMonth = nMonth;
sDate.nDay = nDay;
sDate.nYear = nYear;
}
// Init our date to the same date using the function
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:
struct DateStruct
{
int nMonth;
int nDay;
int nYear;
};
class Date
{
public:
int m_nMonth;
int m_nDay;
int m_nYear;
};
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:
Date cToday; // declare a variable of class Date // Assign values to our members using the member selector operator (.) cToday.m_nMonth = 10; cToday.m_nDay = 14; cToday.m_nYear = 2020;
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:
class Date
{
public:
int m_nMonth;
int m_nDay;
int m_nYear;
void SetDate(int nMonth, int nDay, int nYear)
{
m_nMonth = nMonth;
m_nDay = nDay;
m_nYear = nYear;
}
};
Just like member variables of a struct or class, member functions of a class are accessed using the member selector operator (.):
Date cToday; cToday.SetDate(10, 14, 2020); // call SetDate() on cToday
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:
#include <iostream>
class Employee
{
public:
char m_strName[25];
int m_nID;
double m_dWage;
// Set the employee information
void SetInfo(char *strName, int nID, double dWage)
{
strncpy(m_strName, strName, 25);
m_nID = nID;
m_dWage = dWage;
}
// Print employee information to the screen
void Print()
{
using namespace std;
cout << "Name: " << m_strName << " Id: " <<
m_nID << " Wage: $" << m_dWage << endl;
}
};
int main()
{
// Declare two employees
Employee cAlex;
cAlex.SetInfo("Alex", 1, 25.00);
Employee cJoe;
cJoe.SetInfo("Joe", 2, 22.25);
// Print out the employee information
cAlex.Print();
cJoe.Print();
return 0;
}
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!
8.3 — Public vs private access specifiers
|
Index
|
8.1 — Welcome to object-oriented programming
|
8.3 — Public vs private access specifiers
Index
8.1 — Welcome to object-oriented programming
cAlex.Print();
cJoe.Print();
return 0;
}; ======> LINE 41
Semicolon in line 41 after }
Infact i copy pasted whole code and compiled it and didnt get any error with “}; ” even with semicolon after closing braces.Does compiler ignore that?
Thanks,
Renu
It’s possible to declare stuff after the end of main() — for example, other variables, functions, etc… The compiler treats that ; as a blank statement, which compiles to nothing. So it’s essentially ignored. There’s no reason for that ; to be there (it was a typo), but it doesn’t hurt either. (As a note to future readers, I removed the extraneous semicolon).
I get build errors the on beginning example when trying to initialize manually.
struct DateStruct { int nMonth; int nDay; int nYear; }; DateStruct sToday; sToday.nMonth = 10; ---- Errors here. sToday.nDay = 14; sToday.nYear = 2014; void SetDate(DateStruct &sDate, int nMonth, int nDay, int nYear)...The error is: “expected constructor, destructor, or type conversion before ‘.’ token.
Also, not quite sure why the & reference for the &sDate in the SetDate function?
Is this so just passing the reference instead of whole structure when calling the
function?
Thank you for your help.
p.s. Love these lessons
Hmm, that’s an odd one. Is the code that uses sToday inside a function, or is it floating in global space? Declarations can be in global space, but code that executes instructions can not be. I would put the following code:
inside your main() function and then see if it works. I suspect it will.
Also, as far as the & goes, that means we’re passing a DateStruct by reference instead of by value. This will allow SetDate to modify the actual sDate we pass in instead of just a copy.
This is the whole thing I’m trying…
#include struct DateStruct { int nMonth; int nDay; int nYear; }; int myInt = 5; DateStruct sToday; //sToday.nMonth = 10; *will cause error here //sToday.nDay = 14; //sToday.nYear = 2014; void SetDate(DateStruct &sDate, int nMonth, int nDay, int nYear) { sDate.nMonth = nMonth; sDate.nDay = nDay; sDate.nYear = nYear; } int main() { using namespace std; DateStruct sToday; sToday.nMonth = 10; * works O.K. if I assign here. sToday.nDay = 14; sToday.nYear = 2014; SetDate(sToday, 4, 4, 2008); cout < < "Date values are: " << sToday.nMonth << "/" << sToday.nDay << "/" << sToday.nYear << endl; return(0); }If I comment out setting the global sToday members and use the ones in main()
it works O.K. but not vice versa. So…. you can assign a value to global variables
when they are declared but not members of a struct? (int myInt = 5;)
Unless I’m making a syntax mistake somewhere. Need grouping braces? {} ?
I see what you are trying to do. Yeah, you can’t assign struct variables in global space that way. If you want to initialize your global struct, you have to do it like this:
DateStruct sToday = { 10, 14, 2014 };i have a very fundamental problem.
a ‘class’ is declared. it has one ‘private data-member’ and one ‘public member-function’.
an object (instance of the class) is created after the ‘closing curly brackets and the semicolon’ of the class-declaration.
what is the address of the class ?
what is the address of the class-object ?
what is the address of the member-function ?
please enlighten me to keep up my tempo of persuing c++.
thanks
prabhakar.
The class itself does not have an address, because it is just a definition.
An object of the class does have an address, because it is an actual variable. You can find the address by using the address-of (&) operator:
Member functions also have an address, because you can set a pointer to them, and you can pass their address into a function:
ptr is a pointer to a member function of Foo that takes no parameters and returns an integer. It is being set to the address of the Foo::GetValue() function.
hi alex..
still i am confusing about using strncpy..
following line in ur program how its work i still didnt understand
strncpy(m_strName, strName, 25);
kind regards
strncpy simply copies N character of a zero-terminated string into another string. So the above line copies 25 characters from strName to m_strName.