Constructors and Overloading...

So I have created a C++ program and its finished and functional, but there are a few things I have yet to add to it.

My questions deal with two things: overloading and constructors.

I am not familiar with either of them, but according to my homework assignment I have to implement them. Now, I have read through my book but it vaguely explains these things, so it must be noted that not only do I not know how to implement them in terms of code, but I am not even sure what they do or where to begin.

This program is our instructors way of helping us learn to define classes and use objects, use accessors, mutators, and constructors. Well I understand and have completed all of that aside from constructors.

An explanation of the program: It accepts as input a customers name, street address, zip code, cookie type ordered, and how many cookies where ordered, and on what date they were ordered. It then proves to my teacher that I know how to use accessors by displaying the year the cookies were ordered in main(), since the year was originally a private variable. Also, it invokes a manipulator by asking the user if they would like to change the customer name. Our instructor just wanted us to do these 2 random things to prove we understand how to code and use accessors/mutators. The program then outputs via an output method a report containing all of the information entered by the user. It does not need to loop; it only needs to run once.

Anyhow, to the problem. The instructions say to invoke a default constructor for each attribute (customer name, street address, etc) and also a constructor that accepts arguments for each of those attributes.

I have no idea what this means or what it is used for...

Additionally, he wants us to overload the input and output stream operators so that the objects may be used in standard input and output statements (which i assume he means "cin" and "cout")

I also have no idea what that means or what it is used for...

Any help would be appreciated, but I would also like an explanation of what exactly a constructor does and what the advantages are overloading are, for educational purposes.



#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

class CookieOrder //This is the class i defined
{
public:
void input();
void output();

string get_name();//accessor

void set_name(string new_name);//mutator

string get_address();

void set_address(string new_address);

string get_city();

void set_city(string new_city);

string get_state();

void set_state(string new_state);

int get_zip();

void set_zip(int new_zip);

int get_month();

void set_month(int new_month);

int get_day();

void set_day(int new_day);

int get_year();

void set_year(int new_year);

int get_cookieType();

void set_cookieType(int new_cookieType);

int get_numCookies();

void set_numCookies(int new_numCookies);

private:
string name;
string address;
string city;
string state;
int zip;
int month;
int day;
int year;
int cookieType;
int numCookies;

};

int main()
{
int year;
char choice;
string newCustName;
CookieOrder entry;
cout << "Please enter the customers first and last name.\n";
entry.input();
cout << "The final report for this customer is as follows: \n\n";
entry.output();
cout << "These cookies were ordered in ";
year = entry.get_year();//demonstrating accessor usage
cout << year << endl;
cout << "Would you like to edit the customer name? Enter 'Y' or 'N'.\n";
cin >> choice;
if ((choice == 'Y') || (choice == 'y'))//demonstrating mutator usage
{
cout << "Please enter the new customer name: \n";
getline(cin, newCustName);
cin.ignore(1000, '\n');
entry.set_name(newCustName);
cout << "New customer name saved!\n";
}

cout << "Thank you for using this program! Good-Bye!\n";

return 0;
}

void CookieOrder::input()
{

cout << "Please put a space between them: \n";
getline(cin, name);
cout << "Please enter the customer's street address: \n";
getline(cin, address);
cout << "Please enter the city the customer lives in: \n";
getline(cin, city);
cout << "Please enter the state the customer lives in: \n";
getline(cin, state);
cout << "Please enter the customer's zip code: \n";
cin >> zip;
cout << "Enter the date the order was placed by first entering the numerical form of this month\n";
cout << "(January = 1, February = 2, ...)\n";
cin >> month;
cout << "Input the day of the month the order was placed: \n";
cin >> day;
cout << "Enter the year during which the order was placed: \n";
cin >> year;
cout << "Enter the number that corresponds to the cookie type ordered.\n"
<< "For a reminder, see the chart below.\n\n"
<< "Chocolate Chip" << setw(5) << "1" << endl//my bootleg form of right-aligning...lol
<< "Peanut Butter" << setw(6) << "2" << endl
<< "Sugar" << setw(14) << "3" << endl
<< "Pecan" << setw(14) << "4" << endl
<< "Candy" << setw(14) << "5" << endl;
cin >> cookieType;
cout << "Finally, enter the number of cookies that were ordered: \n";
cin >> numCookies;
cin.ignore(1000, '\n');
}

void CookieOrder::output()
{
cout << name << endl;
cout << address << endl;
cout << city << " " << state << ", " << zip << endl;
cout << "Order Date: " << month << "/" << day << "/" << year << endl;
switch (cookieType)
{
case 1:

cout << "Cookie type: Chocolate Chip" << endl;
break;

case 2:

cout << "Cookie Type: Peanut Butter" << endl;
break;

case 3:

cout << "Cookie Type: Sugar" << endl;
break;

case 4:

cout << "Cookie Type: Pecan" << endl;
break;

case 5:

cout << "Cookie Type: Candy" << endl;
break;
}
cout << "Quantity: " << numCookies << endl;

}

string CookieOrder::get_name()
{
return name;
}

void CookieOrder::set_name(string new_name)
{
name = new_name;
}

string CookieOrder::get_address()
{
return address;
}

void CookieOrder::set_address(string new_address)
{
address = new_address;
}

string CookieOrder::get_city()
{
return city;
}

void CookieOrder::set_city(string new_city)
{
city = new_city;
}

string CookieOrder::get_state()
{
return state;
}

void CookieOrder::set_state(string new_state)
{
state = new_state;
}

int CookieOrder::get_zip()
{
return zip;
}

void CookieOrder::set_zip(int new_zip)
{
zip = new_zip;
}

int CookieOrder::get_month()
{
return month;
}

void CookieOrder::set_month(int new_month)
{
month = new_month;
}

int CookieOrder::get_day()
{
return day;
}

void CookieOrder::set_day(int new_day)
{
day = new_day;
}

int CookieOrder::get_year()
{
return year;
}

void CookieOrder::set_year(int new_year)
{
year = new_year;
}

int CookieOrder::get_cookieType()
{
return cookieType;
}

void CookieOrder::set_cookieType(int new_cookieType)
{
cookieType = new_cookieType;
}

int CookieOrder::get_numCookies()
{
return numCookies;
}

void CookieOrder::set_numCookies(int new_numCookies)
{
numCookies = new_numCookies;
}
Last edited on
OK, FIRST off, you need to put that code into the code tags. They are there for a reason, it makes your code much easier to read.
A constructor is a member function of a given class. It does not merely assign values to the class's member variables but initializes them. (YES, there is a difference between creating and assigning variables vs initializing them!) To create a constructor, you need to create it like a normal member function except the name of the function must be that of your class. For example, if you had a card class, your constructors would be called card(). Constructors have NO return type (as i recall).
Each constructor must have a different set of arguments. This is to make sure that the constructors can be differentiated. The default constructor has no arguments. It creates any object of its class that is given no arguments. So take this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct card
{
    int rank;
    char suit;

    card()
    {
        rank = 0;
        suit = '\n';
    }

    card(int givesuit, char giverank)
    {
        rank = giverank;
        suit = givesuit;
    }
}

int main()
{
    card emptycard;
    card notemptycard(9,'C');
    return 0;
}


Because the first card was created without any constructor arguments, it remained empty and was initialized with a call to the default constructor. Usually the default constructor is used to provide "empty" values to a class object to make it clear that that object has not yet been used.
The second card was created with an argument list. Because that argument list matches the arguments of the second constructor in the class, it calls that constructor to create the card, executing the actions within the constructor.
Keep in mind that although a constructor is designed to construct a class object, it is a function and does not have to consist solely of assignments.
I presume you know what it means to overload a function. It is to create multiple functions of the same name, but without the same argument lists. That way, you can refer to the function by one name but give it different sets of args in each call, and based on the arg lists the compiler then differentiates which one you want to call. Overloading an operator is a slightly different story but I would say it's one of the coolest things in C++ that you should totally know.
Basically, overloading an operator enables it to take on a different meaning when your class objects are used in context with the operator in question. For example let's say I wanted to compare which cards were higher in the above example. I could write a comparison member function to take two cards and compare them or I could just redefine the > and < operators. Another example of an overloaded operator is the cout and cin objects. Those << and >> operators are actually bitwise shift operators, not stream manipulation operators. But by overloading the operators within the cout and cin class objects, they take on a specific meaning that allows them to be used in a different way.
Here's an example.
1
2
3
4
bool operator<(card first, card second)
{
    return first.rank < second.rank;
}

An overloaded operator must have at least one user-defined class as an operand, and must use the same number of operands as the original operator. Overloaded operators do NOT have to be members of a class. However, if they are, you can reduce the number of arguments by one since you have the implicit this operand (the class it is called from). You can overload almost all the operators, but I cannot remember which ones you can't overload. The :: and . operators are among them however. (Yes you can overload operators such as new, delete, () and []! Overloading the subscript operator is how the standard containers are accessed.) In addition, the assignment, subscript and function-call operators must be defined as member functions.
To overload the operator, you first issue a return type, then you type operator, and, without a space, the symbol for the one you want to overload. The above example demonstrates how. You can call an overloaded operator function as you would a normal operator:
1
2
3
4
card first(3,'S'), second(12,'H');
if (first < second)
{ // Some code here...
}

Or you can explicitly call it:
1
2
3
4
card first(3,'S'), second(12,'H');
if (operator<(first,second))
{ // Some code here...
}

It is not advisable to overload some operators, simply because they have important system-level meanings, such as the & operator. You risk screwing up existing code in your program if you did such a thing, so some operators should be more cautiously overloaded. However, some operators, such as the arithmetic, << and >>, and = operators can benefit significantly from overloading. In general you should define at least the < and == operators in your class because these operators are used by the standard containers and algos.
To overload the << and >> operators as your teacher expects, you would create an operator that takes an ostream (such as cout) and your class object, and returns a reference to the ostream argument. Then you would simply output the various members of your class like so:
1
2
3
4
5
ostream& operator<< (ostream& os, const card &thecard)
{
    os << thecard.suit << " " << thecard.rank;
    return os;
}

By redefining those operators a call like this one would then become legal:
1
2
card sixofdiamonds (6,'D');
cout << sixofdiamonds;


Anything I haven't cleared up for you?

EDIT: By the way, this website has tons of good lessons on programming in C++ and I'm sure you could find these topics in there somewhere if you are still confused.
Last edited on
well now, that pretty much cleared it up! thanks, and yeah i submitted my code without code brackets but i thought i had used them, i apologize and am aware of their existence, lol. Thanks so much for taking the time to help me!
You're welcome!
Topic archived. No new replies allowed.