One overloaded function, yet the program doesn't see it that way - c++

The following code has overloaded function CandyBarFunc. First prototype defines the function so that it modifies the value of a structure. Second prototype defines the function so that it just displays the content of a passed structure. The problem is that when I run the console program nothing appears on the screen except the Press Any Key...
I tried to debug it and found out that first prototype works properly(I added the display functionality from the second prototype to the first one) becuase it modified and displayed the contents of the structure. So therefore it seems that overloading didn't work because the second function prototype doesn't get called during execution because nothing is displayed on the console screen. I'm not sure if the signaure is bad because the compiler does't complain about the ambigious function call. Did I miss something obvious in the code?
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct CandyBar
{
char name[40];
double weight;
int calories;
};
void CandyBarFunc(CandyBar & astruct, const char * aname = "Millennium Munch", double aweight = 2.85, int acalories = 350);
void CandyBarFunc(const CandyBar & astruct);
int main(void)
{
CandyBar MyCandyBar =
{
"Hi",
1.5,
456
};
cout << "1" << endl; 'little debug'
CandyBarFunc(MyCandyBar); 'suppose to display the contents of MyCandyBar'
CandyBarFunc(MyCandyBar, "Hello World Candy Bar", 1.25, 200); 'suppose to modify MyCandyBar
CandyBarFunc(MyCandyBar); 'suppose to display the contents of MyCandyBar again'
cout << "2"; 'little debug'
return 0;
}
void CandyBarFunc(CandyBar & astruct, const char * aname, double aweight, int acalories)
{
strncpy_s(astruct.name,aname,40);
astruct.weight = aweight;
astruct.calories = acalories;
cout << "Name: " << astruct.name << endl; 'not suppose to be here, just for debug'
cout << "Weight: " << astruct.weight << endl; 'not suppose to be here, just for _ debug'
cout << "Calories: " << astruct.calories; 'not suppose to be here, just for debug'
}
void CandyBarFunc(const CandyBar & astruct)
{
cout << "Name: " << astruct.name << endl;
cout << "Weight: " << astruct.weight << endl;
cout << "Calories: " << astruct.calories;
}
Exercise:
The CandyBar structure contains three members. The first member holds the brand
name of a candy bar. The second member holds the weight (which may have a fractional
part) of the candy bar, and the third member holds the number of calories (an integer
value) in the candy bar. Write a program that uses a function that takes as arguments a
reference to CandyBar, a pointer-to-char, a double, and an int and uses the last three
values to set the corresponding members of the structure. The last three arguments
should have default values of “Millennium Munch,” 2.85, and 350. Also, the program
should use a function that takes a reference to a CandyBar as an argument and displays
the contents of the structure. Use const where appropriate.

Since MyCandyBar isn't const, the compiler choses the first (reference to non-const) overload.
But seriously, if you want one function to set properties and another function to print them out, please don't abuse overloading by giving them the same name. Just name them differently, no more problems.
Also, in C++ we prefer std::string to fixed-size character arrays and character pointers.

Since MyCandyBar is not const, it will always try to use the function which accepts the non const CandyBar. You can force it to call the other function by casting it to const:
CandyBarFunc((const CandyBar &)MyCandyBar);

Related

(C++) Vector elements seem to disappear after for loop ends

I'm extremely new to C++ (even newer to OOP) and I'm doing my first project that doesn't take place within one .cpp file. I've run into a seemingly simple issue where my vector data seems to be disappearing.
Code chunk inside main.cpp's main function:
vector<Horse> HorseStable(horseAmount); // creating an vector of horse objects based on user input horseAmount
for (int i = 0; i < horseAmount; i++) // sets name for each horse and rider
{
string nameString = "";
string riderString = "";
cout << "Enter name for horse #" << (i + 1) << ": ";
cin >> nameString;
HorseStable[i].setName(nameString);
cout << "Enter name for rider of " << nameString << ": ";
cin >> riderString;
HorseStable[i].setRider(riderString);
system("cls");
}
HorseStable[0].printName(); // a test to see if the horse name stayed inside the vector (it did not)
Entire Horse.h file:
#pragma once
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
class Horse
{
private:
std::string name;
std::string rider;
public:
// these three ints were supposed to be private, but I couldn't access
// maxRunningDistPerSecond as a displayHorse() function parameter from main
// maybe figuring out my first issue will help with this, as I was attempting
// HorseStable[0].displayHorse(maxRunningDistPerSecond)
int maxRunningDistPerSecond;
int distanceTraveled;
int racesWon;
Horse() // default constructor
{
std::string name = " ";
std::string rider = " ";
int maxRunningDistPerSecond = 100;
int distanceTraveled = 0;
int racesWon = 0;
};
int runASecond(int, int);
int sendToGate(int);
void displayHorse(int);
std::string setName(std::string); // sets the horse name based on user input from main.cpp variable
std::string printName(); // simply prints the horse name, I don't believe my issue is here
std::string setRider(std::string);
std::string printRider();
};
Code chunk inside Horse.cpp:
std::string Horse::setName(std::string nameString) // takes user input for horse name
{
Horse::name = nameString;
return std::string(nameString);
}
std::string Horse::printName() // prints the horse's name
{
return std::string(name);
}
setName() and getName() work perfectly within my for loop inside main.cpp, but all data seems to disappear when I attempt them after the loop ends. I've looked for hours for solutions, but had to revert to this stable build after nothing worked. I'm not very good with pointers and passing by reference, but these seem to be the only things that will work. Is it possible that I was using pointers wrong? Should I be creating a vector of Horse pointers, rather than a vector of actual Horse objects?
My other issue:
If you've noticed my public members that are supposed to be private in Horse.h, I cannot access them when private as parameters from functions called in main. This makes some sense, as my function call in main looked like this:
HorseStable[0].displayHorse(distanceTraveled)
I'm not sure how I could refer to each element of the vector within the Horse class, which seems like the only way distanceTraveled would be reachable as private. My professor wants the variables in question to be private, which makes this an issue. The user defines the amount of Horse objects, which means I can't just declare a few named Horses and simply displayHorse(distanceTraveled) them.
Function declaration from Horse.cpp:
void Horse::displayHorse(int distanceTraveled) // attempts to show a graphic of the race progress
{
if (distanceTraveled >= 50)
{
std::cout << "|-> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 100)
{
std::cout << "|--> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 150)
{
std::cout << "|---> |" << " " << name << ", ridden by " << rider;
} // this goes on up to 1000, but this is all that's necessary for posting
I apologize if my formatting isn't up to par, but this assignment has really been stressing me out. I've been understanding all the new material, but it always seems like pointers and referencing are the things that render my assignments unusable.

storing an object name during construction of another object

I wanted to create objects from the class “takeSnapshots” that would learn, upon their instantiation, the name of another object from the class “lock” that they could query later as the state of the “lock” object changes. I can think of multiple ways of letting the object from class “takeSnapshots” know which object it is to query (like including the name of the “lock” object as part of the call to its member functions). But, I thought it better to take care of the relation in the beginning and not worry later if I am calling the correct object combinations.
The included code shows stripped down versions of the two classes and example instantiations created in main.
I have included the outputs on each line following their respective couts.
What I expected was that the constructor of “takeSnapshots” would store away the address of the “lock” object. Then I could use it later when taking a snapshot. You can see that what gets stored away (at least when I use it to get numWheels) is a few addresses off from the address that the “lock” object thinks it has for numWheels.
I am mostly interested in knowing why this code does not work the way I expect, i.e, if this is not a good architectural idea, that is one thing. But with the behavior I’m seeing here, I’m clearly not ready to use pointers in anything complicated and I don’t want to give up on the basic architecture just because of erroneous implementation. Any help would be greatly appreciated.
// simpleTest.cpp : Demonstrates problem I'm having understanding
// pointer to an object.
#include "stdafx.h"
#include<iostream>
using namespace std;
class lock {
public: //Just while I run a test.
int numWheels;
lock(int numW) {
numWheels = numW;
cout << " \n In \"lock\" constuctor, address and value of numWheels
" << &numWheels << " " << numWheels << endl;
} //Values from console: 0034F874 and 4
};
class takeSnapshots {
lock* localLock;
public:
takeSnapshots(lock myLock) {
localLock = &myLock;
cout << " \n In \"takeSnapshots\" constuctor, address and value of
numWheels " << &localLock->numWheels << " "
<< localLock->numWheels << endl;
//Values from console: 0034F794 and 4 "Same value, but not the same
//address as expected from "lock."
}
void takeASnapSnapshot() {
cout << " \n When taking a snapshot, address and value of numWheels
" << &localLock->numWheels << " " << localLock->numWheels <<
endl;
//Values from console: 0034F794 and 2303449 "No longer even the
// same value as expected from "lock."
}
};
int main()
{
lock yourLock(4);
takeSnapshots myShots1(yourLock);
cout << " \n In main (from \"yourLock\"), address and value of
numWheels " << &yourLock.numWheels << " " << yourLock.numWheels <<
endl;
//Values from console: 0034F874 and 4 "Still the same values as set
//in the constructor of "lock."
//Take a picture
myShots1.takeASnapSnapshot();
return 0;
}

how can a void function be called to the main, if there are no returns?

I wanted to create a function that retrieves all the information from previous functions within the same Class, and prints the values that were returned in the format of a bunch of cout statements, there is nothing for me to return in this PrintStatement() function, so I would create a void function, correct? My issue is in the int main(), I cannot cout a void function.
this is my account header file, and the function piece from my account.cpp file.
class Account {
public:
//Object constructor
Account(char firstName[], char lastName[], char sinNumber[], double balance, int accountType, int transactions);
//Object operations
double DepositAmt(double amount);
double WithdrawAmt(double amount);
void PrintStatement();
double getFinalBalance(double fbal);
string getAccountType();
double getTransactions (double Deposit, double Withdraw);
private:
//Object properties
char firstName[255];
char lastName[255];
char sinNumber[255];
double balance;
int accountType;
int transactions;
};
void Account::PrintStatement()
{
cout << "First Name: " << firstName << endl;
cout << "Last Name: " << lastName << endl;
cout << "SIN Number: " << sinNumber << endl;
cout << "Account Type: " << accountType << endl;
cout << "Final Balance: " << balance << endl;
cout << "Transactions: " << transactions << endl;
};
the global variables have already been initialized.
What I've tried:
I originally tried to cout << account.PrintStatement() << endl; however I get an error C2679 (binary '<<' : no operator found which takes a right-hand operand of type 'void' (or there is no acceptable conversion)
I thought maybe changing things to apply to a string function instead would work, but instead I get a bunch of int conversion errors etc.
I'm unsure of what to do.
I am required to put these in a function just to be clear.
I tried using this question https://stackoverflow.com/questions/12766858/how-to-call-void-function-from-main to help me, it made sense that the poster was using a reference, but I do not have that. Is there another way?
I originally tried to cout << account.PrintStatement() << endl;
Well, the expression account.PrintStatement() is abject nothingness because the function has a void return type. As you've indicated, the function returns nothing, so there is nothing to stream to cout.
The function itself has already streamed a bunch of stuff to cout, fulfilling all your couty needs. So, simply invoke it:
account.PrintStatement();
That's it!
Just call the method on your instance of the class. It doesn't need to return anything; it will do the counts you want and then return to main.
When we use cout<<something_here, the compiler will interpret it as "print the value of something_here". Now, something_here can be a lot of things. When it is a function, cout will print the value returned by the function. In your case, the return type is void i.e. nothing. So, there is nothing to print.
To fix your issue, you can directly call account.PrintStatement(); since you have already printed what you wanted to print inside this function.

Syntax Query, calling modules in Visual C++

I have tried to adapt my knowledge of modularity to Visual C++ however, upon what seems to be an endless search scouring for syntax, I simply can't get this right. Basically in this code, the menu is called first, once the user enters their choice (only coded option 1 thus far) to return that value to the main, which then steps into the if statement and calls fahrenheit. I am requesting the syntax for passing by reference, I know C#'s syntax for this, but not Visual C++
Here's the code.
// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void Celsius()
{
}
void fahrenheit()
{
cout << "Success!" << endl; //....Outputs this just to see if the module is being called properly.
}
int menu(int Mystring) //....I was testing this syntax to pass the variable.
{
cout << "What would you like to do : " << endl;
cout << "1) Fanreheit to Celsius" << endl;
cout << "2) Celsius to Fahrenheit" << endl;
cout << "Choice : " ;
cin >> Mystring;
return Mystring;
}
int main()
{
int celsius = 0;
int fahrenheit = 0;
int Mystring = 0;
menu(Mystring); //....Testing this syntax to pass Mystring to menu.
if (Mystring == 1) //....I was hoping the menu would return Mystring as value = 1.
{
fahrenheit(); //.......I want this to call fahrenheit module if Mystring = 1
}
}
The "things" you're talking about aren't called modules, but functions. That's a pretty big difference and I think you should know it, since you won't understand nearly any article without that knowledge.
That being cleared, the problem in your code is, that you pass the variable by value (int menu(int Mystring)), while - in order to change it inside the function - you need to pass it by reference or pointer:
int menu(int &Mystring)
There are plenty of articles about functions in C++. You should check them out probably.

Why does my program not react to any arguments?

I have a simple test program in C++ that prints out attributes of a circle
#include <iostream>
#include <stdlib.h>
#include "circle.h" // contains the Circle class
using namespace std;
void print_circle_attributes(float r) {
Circle* c = new Circle(r);
cout << "radius: " << c->get_radius() << endl;
cout << "diameter: " << c->get_diameter() << endl;
cout << "area: " << c->get_area() << endl;
cout << "circumference: " << c->get_circumference() << endl;
cout << endl;
delete c;
}
int main(int argc, const char* argv[]) {
float input = atof(argv[0]);
print_circle_attributes(input);
return 0;
}
when I run my program with the parameter 2.4 it outputs:
radius: 0.0
diameter: 0.0
area: 0.0
circumference: 0.0
I've previously tested the program without the parameter, but simply using static values, and it ran just fine; so I know there's nothing wrong with the class I made...
So what did I do wrong here?
argv[0] is the program name. You want argv[1] for the first argument.
Also, check that argc is at least two before trying to access it. You might also consider std::stoi, std::istringstream or strtod rather than atoi for conversion, since they can detect bogus input.
Finally, why are using new when an automatic variable will suffice? You should get out of that habit straight away, or spend the rest of eternity debugging memory leaks.
argv[0] is the name of the executable being invoked.
Your first command line parameter will be in argv[1].
To make sure that your program does not silently fail again, you should check how many parameters you actually have and if the atof returns a value, and show a message to the user explaining the issue accordingly.