Result of method used to call another method yields inconsistent results - c++

I currently have to write a program that allows a user to pick between two objects to test.
This isn't the same program exactly but it's the same premise.
class defined by header file
#include <iostream>
class example {
private:
int x;
public:
example() {
x = 10;
}
void setNum(int input) {
x = input;
}
int getNum() {
return x;
}
};
Test main and selectObj method
#include <iostream>
#include "Header.h"
example selectObj(example A, example B) {
int selection;
std::cout << "Select object 1 or 2: ";
while (true) {
std::cin >> selection;
if (selection == 1)
return A;
else if (selection == 2)
return B;
else
std::cout << "Inavlid option, try again: ";
}
}
int main() {
example test1, test2;
selectObj(test1, test2).setNum(25);
std::cout << selectObj(test1, test2).getNum();
return 0;
}
selectObj is supposed to return an object. It runs but it isn't doing what setNum is supposed to do.
Suppose you choose option 1 for both calls of selectObj. It looks something like this.
Select object 1 or 2: 1
Select object 1 or 2: 1
10
It should have printed out 25 but instead, setNum isn't really changing the value of test1.
However, if I write
test1.setNum(25);
std::cout << test1.getNum();
Then it does indeed set test1's x value to 25.
Again, this isn't exactly like the program I had written (it is changed now and wouldn't like to rewrite that). However, it is an identical representation of the same concept.

The problem is that you're passing and returning the arguments by value instead of reference. To solve this you can pass and return the arguments by reference as shown in the below modified code:
main.cpp
#include <iostream>
#include "Header.h"
//return and pass by reference
example& selectObj(example &A, example &B) {
int selection;
std::cout << "Select object 1 or 2: ";
while (true) {
std::cin >> selection;
if (selection == 1)
return A;
else if (selection == 2)
return B;
else
std::cout << "Inavlid option, try again: ";
}
}
int main() {
example test1, test2;
selectObj(test1, test2).setNum(25);//this sets the value of x member of the object that the user chooses
std::cout << selectObj(test1, test2).getNum();
return 0;
}
The output of the above program when the user enters option 2 is:
Select object 1 or 2: 1
Select object 1 or 2: 1
25

Related

Why my code is print for 4 in the line head?

It is my code in the following instruction:
#include <iostream>
using namespace std;
class learning
{
public:
static int func(int var)
{
return var;
}
inline bool func(bool var=2 > 1)
{
bool& va = var;
int num = func(3);
num += va;
cout << num << " ";
return num;
}
};
int main()
{
learning len;
cout << "Testing " << learning::func(6) << " " << len.func();
return 0;
}
Why my cmd is print 4 Testing 6 1 but not is Testing 6 1 4?
I believe that what you are seeing is that the order of operator-arguments-evaluation is implementation-specific (at least prior to C++17). For further enlightenment, you might try running this program:
#include <iostream>
using namespace std;
static int DebugFunc(int i)
{
fprintf(stderr, "DebugFunc called with argument %i\n", i);
return i;
}
int main()
{
cout << DebugFunc(1) << DebugFunc(2) << DebugFunc(3);
return 0;
}
On my compiler (clang++/MacOS), the program outputs this (Note that the "DebugFunc called" lines are fprint()'ed to stderr rather than using cout, to avoid complicating the output of the cout line in main()):
DebugFunc called with argument 1
DebugFunc called with argument 2
DebugFunc called with argument 3
123
... which is reasonable, but I think MSVC is free to evaluate the arguments in a different order, and output e.g. this:
DebugFunc called with argument 3
DebugFunc called with argument 2
DebugFunc called with argument 1
123
If MSVC is evaluating the arguments from right-to-left, that would explain why your program's "4" is printed before its "Testing".

Editing class private in C++

I am working on this code. It is not yet done. The problem is that I do not get why I cannot update numAccount in my simple_account.h. It just keeps printing out "1" if I print out numAccount. Can anyone tell me why I cannot access and change the private value here?
main.cc
#include <iostream>
#include "simple_account.h"
using namespace std;
int main() {
char job;
int i = 0;
while (true) {
cout << "Job?" << endl;
cin >> job;
if (job == 'Q')
break;
if (job == 'N') {
Admin* user = new Admin[10];
(user+i)->newAccount(i);
cout << "i: " << i << endl;
i++;
}
}
simple_account.h
#pragma once
#include <iostream>
class Account {
public:
int id;
int b = 0;
};
class Admin {
class Account {
int id;
int b = 0;
};
int numAccount = 0;
Account **acnt[10];
public:
void newAccount();
void deposit(Account id, int money);
void withdrawal(Account id, int money);
void transfer(Account id1, Account id2, int money);
void check(Account id);
};
simple_acount.cc
#include "simple_account.h"
void Admin::newAccount() {
numAccount += 1;
}
The problem occurs when you press 'N' to open a new account.
if (job == 'N') {
Admin* user = new Admin[10];
(user+i)->newAccount(i);
cout << "i: " << i << endl;
i++;
}
This code creates ten new Admin objects, and initializes each one with the default constructor. Each Admin has its own numAccount member, which is initialized to zero because that's the default value you specified here: int numAccount = 0;
After creating ten Admin objects, the code then picks one with (user+i) and calls newAccount(i). This should not compile, because the newAccount() method does not take a parameter. But if it worked, it would increment that one Admin's numAccount member to 1 from the initial 0.
(There's another problem here, which is that when i reaches 10, you will be trying to call newAccount() on something that's outside your array of Admin objects, so you're going to see some undefined behavior.)
How to fix this.... depends on what you're trying to do. As suggested, you can make numAccounts a static member of the Admin class. But I think you'll need to review your design: what is an Admin, and how many should there be?

Printing all palindrome numbers in a given range

I'm trying to write a program that would print all palindrome in range [a, b]. I've written this so far, but nothing is printed after I input the values for a, b. What is missing?
#include "stdafx.h"
#include <iostream>
using namespace std;
int t = 0, rmd, z, a, b;
int reverse() {
while (z != 0) {
rmd = z% 10;
t = t * 10 + rmd;
z/= 10;
}
return t;
}
int palin() {
if (a == reverse()) {
return 1;
}
else
return 0;
}
int main() {
cout << "a: "; cin >> a;
cout << "b: "; cin >> b;
while (a <= b) {
z = a;
if (palin())
cout << a << endl;
a++;
}
system("pause");
return 0;
}
The problem is that the variable t is not local to your reverse() function. Its value survives to the following invocation, so the result of reverse becomes junk unrelated to the actual call.
You need to make t local to reverse() in order to fix this problem.
In general, it is a good idea to develop a habit of declaring your variables in the innermost scope to which they could belong without breaking your code. In this case, this would be the scope of reverse() function for t, and the scope of main for the remaining variables; palin should take a as its parameter.
Your use of variables is what is confusing you. The actual issue is not setting t to zero every time you call reverse, but you should think about how you use variable scoping and what functions actually do. Right now you have 2 procedures, that perform actions on global data. Instead try to formulate the problem using functions that accept arguments, and return a result.
#include <iostream>
using namespace std;
int reverse(int z) {
int t = 0;
int rmd;
while (z != 0) {
rmd = z % 10;
t = t * 10 + rmd;
z/= 10;
}
return t;
}
int palin(int z) {
return z == reverse(z);
}
int main() {
int a, b;
cout << "a: "; cin >> a;
cout << "b: "; cin >> b;
while (a <= b) {
if (palin(a)) {
cout << a << endl;
}
a++;
}
system("pause");
return 0;
}

Function must return a value

I am trying to make a text based RPG and i'm fairly new to c++. I understand that I need to return a value, but when I try and return CharacterName or CharacterRace it comes up with unresolved externals errors. I'd really appreciate the help guys, thanks :)
CharacterCreation.h
#include <string>
#include <iostream>
void petc(), ConsoleClear(), petc(), EnterClear();
std::string CharacterName, CharacterRace;
Main.cpp
#include <iostream>
#include <limits>
#include <string>
#include <string.h>
#include "CharacterCreation.h"
std::string CharacterCreation();
int main()
{
CharacterCreation();
}
std::string CharacterCreation(int RaceChoice, int RaceChoiceLoop)
{
RaceChoiceLoop = 0;
std::cout << "Welcome to the character creation V 1.0.0" << std::endl;
EnterClear();
std::cout << "Choose a name: ";
std::cin >> CharacterName;
std::cout << CharacterName << std::endl;
EnterClear();
while (RaceChoiceLoop == 0)
{
std::cout << "(1) Human - Human's race perks: + 5 to Magic | + 1 to Sword Skill" << std::endl;
std::cout << "(2) Elf - Elve's race perks: + 5 to Archery | + 1 to Magic" << std::endl;
std::cout << "(3) Dwarf - Dwarven race perks: + 5 to Strength | + 1 to Archery" << std::endl;
std::cout << "Choose a race, " << CharacterName << ": ";
std::cin >> RaceChoice;
if (RaceChoice == 1)
{
RaceChoiceLoop = 1;
CharacterRace = "Human";
}
else if (RaceChoice == 2)
{
RaceChoiceLoop = 1;
CharacterRace = "Elf";
}
else if (RaceChoice == 3)
{
RaceChoiceLoop = 1;
CharacterRace = "Dwarf";
}
else
{
std::cout << "Invalid Option";
EnterClear();
RaceChoiceLoop = 0;
}
}
}
void petc()
{
std::cout << "Press Enter To Continue...";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
void EnterClear()
{
std::cout << "Press Enter To Continue...";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
system("cls");
}
void ConsoleClear()
{
system("cls");
}
A declared std::string function should return a string and this is not the same as printing it on the screen, use return "something" inside the function otherwise declare it void.
The "unresolved externals" message isn't directly caused by your returning a value.
It's a linker error, and only occurs because compilation succeeded.
The cause is that you're declaring, and calling, this parameter-less function:
std::string CharacterCreation();
but you're defining this function with two parameters:
std::string CharacterCreation(int RaceChoice, int RaceChoiceLoop)
The declaration and the definition must match.
From the looks of it, you don't actually want the parameters and should use local variables instead:
std::string CharacterCreation()
{
int RaceChoice = 0;
int RaceChoiceLoop = 0;
// ...
Problem is that the function CharacterCreation() (taking no arguments) is never defined, and thus the linker cannot find it.
Try substituting in the following:
std::string CharacterCreation(int, int);
int main()
{
CharacterCreation(1,1);
}
This will call the CharacterCreation function you have implemented below the main function. Doing this I can compile (and link) your code :)
As I have pointed in my comment before, your CharacterCreation method does not return any value, although you have defined a string as an expected one.
What you most likely want to do is either change CharacterCreation signature to:
void CharacterCreation(int RaceChoice, int RaceChoiceLoop)
and keep the current implementation
or pack all your console output in a string and return it at the end of the method.
Then in main()
string result = CharacterCreation();
can retrieve this value and you can print it in main

Error with uninitialized variables and returns

I'm having some problems with my program which I do not understand.
On line 72, I get the error: "error C4700: uninitialized local variable 'sumInEuros' used" however surely it is initialized as I am using it to store a calculation?
Also on line 66 I get "error C4716: 'showPriceInEuros': must return a value" - why must this return a value? the function is simply meant to output a message to the console.
I'm using VS13 and it's c++.
Any help would be very much appreciated, because I am stuck!
Thanks!
#include <iostream> //for cin >> and cout <<
#include <cassert> //for assert
#include <iomanip> //for endl
#include <Windows.h>
using namespace std;
void processAPrice();
int getPriceInPounds();
int convertPriceIntoEuros(int pounds);
int showPriceInEuros(int pounds, int euros);
int calculateSum(int euros);
void produceFinalData(int sum, int numberOfPrices);
int main()
{
char answer('Y');
int numberOfPrices(0);
while (answer = 'Y')
{
processAPrice();
numberOfPrices++;
cout << "Continue? (Y/N)";
cin >> answer;
}
if (numberOfPrices > 0)
//produceFinalData(sum, numberOfPrices);
system("PAUSE"); //hold the screen until a key is pressed
return(0);
}
void processAPrice() //
{
int pounds = getPriceInPounds();
int euros = convertPriceIntoEuros(pounds);
int sum = showPriceInEuros(pounds, euros);
calculateSum(euros);
}
int getPriceInPounds() //
{
int priceInPounds;
cout << "Enter a price (in Pounds): /234";
cin >> priceInPounds;
return priceInPounds;
}
int convertPriceIntoEuros(int priceInPounds) //
{
const int conversionRate(0.82);
return priceInPounds / conversionRate;
}
int showPriceInEuros(int pounds, int euros) //
{
SetConsoleOutputCP(1252);
cout << "The Euro value of /234" << pounds << "is: \u20AC" << euros;
}
int calculateSum(int euros) //
{
int sumInEuros;
sumInEuros = (sumInEuros + euros);
return sumInEuros;
}
void produceFinalData(int sum, int numberOfPrices) //
{
SetConsoleOutputCP(1252);
cout << "The total sum is: \u20AC" << sum;
cout << "The average is: \u20AC" << (sum/numberOfPrices);
}
Well, the showPriceInEuros function is not returning the int it promises to return in its signature. That's the error.
If the function is not supposed to return a value, you should declare its return type as void:
void showPriceInEuros(int pounds, int euros);
//^^
and then:
void showPriceInEuros(int pounds, int euros) {
SetConsoleOutputCP(1252);
cout << "The Euro value of /234" << pounds << "is: \u20AC" << euros;
}
of course.
surely it is initialized as I am using it to store a calculation?
The calculation is based on the variable's uninitialised value:
sumInEuros = (sumInEuros + euros);
^^^^^^^^^^ not initialised
Perhaps you could declare it static, so that its value is preserved between calls to the function, in order to calculate the sum of all the values you pass to the function. Usually, it would be better to use a class to manage persistent data like this, with member functions to update and access it.
why must this return a value?
Because you say it does:
int showPriceInEuros(int pounds, int euros)
^^^
If it shouldn't return a value, change the return type to void.
You do not initialize sumInEuros in this function. You store a result in it - that's true but to calculate the result you are using the uninitialized value.
int calculateSum(int euros) //
{
int sumInEuros;
sumInEuros = (sumInEuros + euros);
return sumInEuros;
}
Answering the question from below:
I would probably create a class PriceCalculator which has all the functions of your algorithm plus the internal state:
class PriceCalculator {
int m_sumInEuros;
public:
PriceCalculator()
: m_sumInEuros(0) { }
void processAPrice(int price);
int getSumInEuros() const { return m_sumInEuros; }
private:
void updateSum(int priceInEuros);
};
From your main function you should create an object of this type and give it the prices you want to sum. Do not do any console input from your class.
int main()
{
PriceCalculator calc;
char answer('Y');
int numberOfPrices(0);
while (answer = 'Y')
{
int priceInPounds;
cout << "Enter a price (in Pounds): /234";
cin >> priceInPounds;
calc.processAPrice(priceInPounds);
numberOfPrices++;
cout << "Continue? (Y/N)";
cin >> answer;
}
...
You might want to think about adding the numberOfPrices to your calculator class as well. At the end you will do all the operations in your class but the user input and console output outside your class. Your class can be tested automatically this way and is completely independent from the user interface.