Hello I work on a project for university which has to contain classes.
I can't paste them here because it would take a lot to read hundreds of rows, but I have a class USER which works perfectly, but I also have a MainMenu() function written right before main(),which is the only one I call in main(), made with switch, which is supposed to redirect the console to classes' submenus or to show objects for every class, it depends on class.
Ok, from this MainMenu when I choose to go to Users List option, I want the console to show me the list of users, that means, all user class objects I created in main(). I thought of creating a new function with reference to class, but I don't know how to use it in this situation when I don't call it in main, and however i need to reffer to all objects in that class not to mention a specific object..
How can I do this because I only call that MainMenu() in main(), not write it here to be able to use the objects directly?
Be kind to me, I'm a beginner and I never dealt with this type of requisites. I would be grateful if you could help me solve this.
Have a nice day.
#include<iostream>
using namespace std;
class user{};
class B{};
class C{};
void MainMenu()
{
cout << " Main Menu" << endl;
cout << endl;
int chosenoption;
cout << "1.Users List" << endl;
cout << "2.Class B Submenu" << endl;
cout << "3.Class C submenu" << endl;
cout << "Type here the number of the option you want to choose: ";
cin >> chosenoption;
system("pause");
switch (chosenoption)
{
case 1:
system("cls");
cout << "There should be shown the list of users, here the only users i created in main are u1 and u2, and i need to make them and their attributes appear in this screen" << endl;
break;
case 2:
system("cls");
ClassBSubmenu();
break;
case 3:
system("cls");
ClassCSubMenu();
break;
default:
cout << endl;
cout << "Choose one of the available options only!" << endl;
cout << "Type here: " << endl;
}
}
void main()
{
User u1(...);
User u2(..);
}
ClassBSubmenu and ClassCSubmenu are functions created before MainMenu, but I haven't edited them too much
You might want to have an array of Users which you pass to the MainMenu() function.
User u[] = { User(...), User(..) };
When you pass an array, you are actually passing a pointer to the first element in the array, so the Users could be modified in MainMenu() and the changes would exist in main().
void MainMenu( User users[] )
{
...
users[0]
MainMenu( u );
Related
I am working on something as a starter at coding, I want to get better so I'm practicicing by making a small program. Now, my aim is to attack a monster and then display its hp and then attack again and display the new HP. I've tried many different loops but each time the program doesn't save the new hp and just gives me the same hp instead of taking it away further. Any help is greatly appreciated, I've tried looking online but I can't seem to find an answer for this.
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
int hollowHP();
int blade();
int main() {
srand(time(NULL));
int damage = blade();
int health = hollowHP();
int newHP = health - damage;
int newDamage = rand() % 11;
int remainingHP = newHP - newDamage;
string answer;
cout << "A hollow stands before you with " << hollowHP() << " amount of HP!"
<< endl;
cout << "fight or flight?" << endl;
cin >> answer;
if (answer == "fight") { cout << "Your blade did " << damage << " amount of
damage!" << endl << "the hollow now has: " << newHP << " HP" << endl; }
if (answer == "flight") { cout << "You have failed to protect those in need,
others will come to take the job off your hands.. coward." << endl; }
do {
cout << "continue fighting?" << endl;
cin >> answer;
if (answer == "yes") {
cout << "Your next attack did " << newDamage << " amount of damage!"
<< endl << "the hollow now has: " << newHP - newDamage << " HP" << endl;
} if (answer == "no") {
cout << "you tried i guess" << endl;
}
} while (health != 0);
cout << "Hurray! You've defeated the hollow and saved many innocent lives!
You're a true hero." << endl;
system("pause");
return 0;
}
int hollowHP() {
int hollow = 50;
return hollow;
}
int blade() {
int slash = 1;
int spiritEnergy = rand() % 11;
int totalSlash;
totalSlash = slash + spiritEnergy;
return totalSlash;
}
Onk_r has the right answer: static variables within the body ({}) of a function 'stick around'. Specifically, the expression which initializes the value of a static variable within a function body is executed only once, so the next time you call that function whatever value it had last will remain.
However, that won't solve your problem: your code is written with the assumption that every time you use a variable the expression that initialized it will be executed. When you use the name damage, for instance, the program will not execute the function blade(). Damage will only receive the value returned by blade() the one time, when you declared the variable damage:
int damage = blade();
That line only ever executes once in the whole lifetime of the program. Similarly, newHP will only ever have the value of health - damage at the time it was initialized. When damage was initialized, if blade() returned 8, then newHP will always have the value 42;
C++ doesn't store expressions; it evaluates them. That is what the type system ensures: the type stored in damage is int, it cannot have the type "expression" (not a thing in C++, though there are all kinds of ways implementing something like that). When you assign a variable, the value of the expression is stored, not how it was calculated. Every time the user attacks you really need to do something like:
newHP = health - blade();
/* Output message */
health = newHP;
Like Norhther said.
You are relying on functions to store state here, too, which isn't bad but in C++ you can, and generally should, do better. Specifically, class Hollow or the easier struct Hollow would be better than some variables floating around inside main().
for saving value in function in C++ or C for future use you can simply declare it as static and when leaves I mean return from function set that variable to that value which you want to save.
I've searched on the web and can't find any solutions to my problem I hope you can help.
So I have constructed an abstract base class and have two derived classes that represents different experiments. (one is actually a derived derived class of my base class) And I made a map as such in a separate header file to store different types of experiments.
//Map class template to store name of experiment and the experiment within a project
typedef map <string, baseData <double>*> ExpContainer;
void search(string searchName, ExpContainer exps) {
ExpContainer::iterator Iter;
Iter = exps.find(searchName); //finds the entry corresponding to searchName and returns the iterator
if (Iter != exps.end()) { //need this as if entry is not found, the return will be end iter.
cout << "Found the experiment " << Iter->first << "." << endl;
Iter->second->print();
}
else {
cout << "Sorry, experiment " << searchName << " is not found" << endl;
}
}
The print() function is different for each experiment type and I know there's a problem called slicing so I've made sure that print() is virtual in the base class. Here's my base class:
namespace mynmsp {
//base class of data can be measurements or errors
template < class T> class baseData {
public:
virtual void print() =0;
virtual ~baseData() {
cout << "Destructor called for the base class." << endl;
}
};
}
Then in my main.cpp I've constructed different types of experiment and I want to print them. Each experiment class has different implementation of the print function that overrides the print function from the base class, like:
void print(){ //do something };
And in my main.cpp I have the map defined as:
ExpContainer project;
And after I have constructed each experiment, I've asked the user for the name of the experiment (expName) and inserted into project as such:
project[expName] = &expC;
I think the insertion is fine as I tested the size of project and it was correct.
However, a runtime error occured when my search function was called like this:
search(name, project);
I don't know if there's a problem with slicing or with my pointers?
I tried to make print() a virtual function in each derived class but that doesn't seem to work either.
Apologies for the long question, please help!
Edit: I've constructed my experiments inside a do while loop while project is declared outside. The whole code is very long but its basics is something like this:
string repeatstr; //user input whether to repeat do while loop or not
bool repeat = true; //condition for staying inside do while loop
ExpContainer project; //declared project to store experiments
do {
string expName;
string ans1; //character to store user input
cout << "What is the name of your experiment? " << endl;
cin >> expName;
cout << "Is this a experiment C ? (y/n)" << endl;
cin >> ans1;
if(ans1 =="y"){
//call the constructor for expC
project[expName] = &expC;
}else {
//call the constructor for expB
project[expName] = &expB;
}
cout << "Do you want to enter another experiment? (y/n)" << endl;
cin >> repeatstr;
if (repeatstr == "n") { repeat = false; }
}while (repeat); //loop over this do-while loop while repeat is true
cout << "There are " << project.size() << " in this database." << endl;
//to retrieve info from a certain experiment
string input, name;
cout << "Would you like to retrieve any experiments (y/n)? " << endl;
input = EitherInput("y", "n");
if (input == "y") {
cout << "Please enter the name of the experiment you want to retrieve: " << endl;
cin >> name;
search(name, project); //code breaks down here!
}
You are saving a pointer to the object that was already destroyed. You can check the addresses that you have in the map, most probably they are the same. You should store your experiment object in dynamic memory
if(ans1 =="y")
{
project[expName] = new expC();
} // Scope ends here and all variable created in it will be destroyed.
else
{
project[expName] = new expB();
} // Scope ends here and all variable created in it will be destroyed.
And after you are done with them you need to call delete on each pointer to avoid memory leak. Also you need to check if the items in the map are already existing, otherwise you will loose pointers to allocated memory which is automatically a memory leak.
I would recommend you to use std::share_ptr< baseData<double> > instead of bare baseData<double>*. Here you can read more about it. And also consider using typedef in order to have more clear syntax.
P.S.
The function
void search(string searchName, ExpContainer exps)
will copy whole map to its body. Use constant reference instead
void search(string searchName, const ExpContainer& exps)
But then you'll also need to declare function print as const:
virtual void print() const = 0;
and override it with const modifier:
virtual void print() const override;
And use constant iterator ExpContainer::const_iterator Iter
I can start wit hsaying that I'm kind of new to programming.
I got an assigment to create first a class bank account that holds one singel bank account, and also a class Bank that holds all bankaccounts in a vector or array.
One method that had to be included was that it should print out all the accounts in a specific Bank vector.
What I don't understand is what arguments I should pass in to such a method and also how do I call it from the main function where the vector is created.
This is what I've got so far:
void skriv_kontolista(vector <Konto>& nyttKonto)
{
for (unsigned int i = 0; i < nyttKonto.size(); i++)
{
cout << "Konto: " << i << endl;
cout << "Innehavarens kontonummer: " << nyttKonto[i].nummer << endl;
cout << "Innehavarens namn: " << nyttKonto[i].innehavare << endl;
cout << "Innehavarens saldo: " << nyttKonto[i].saldo << endl;
cout << "Innehavarens r\x84ntesats: " << nyttKonto[i].rantesats << endl;
}
}
Is that the right way to do it, and if so, how do I call this method from my main function?
Sorry if my english is bad, it's not my native language.
Thanks in advance.
The code looks OK; it should work. However, this
One method that had to be included was that it should print out all
the accounts in a specific Bank vector.
leads me to believe that skriv_kontolista should be a method in class Bank. Your skriv_kontolista function looks like it's not a method in class Bank (but I don't know for sure).
If indeed it should be a method of class Bank, you should have it in your code like this:
class Bank
{
...
void skriv_kontolista(vector <Konto>& nyttKonto)
{
...
}
...
}
In addition, a method has access to all the fields of the class. One of the fields is the vector that the method must print, so there is no need to send it as a parameter to the function!
class Bank
{
void skriv_kontolista() // no need to have any parameters
{
...
cout << "Innehavarens namn: " << nyttKonto[i].innehavare << endl;
...
}
vector <Konto>& nyttKonto; // a field of the class
}
How to call it from the main function:
int main()
{
Bank bank1, bank2, bank3;
...
bank1.skriv_kontolista();
bank2.skriv_kontolista();
bank3.skriv_kontolista();
}
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.
I am attempting to learn C++ (currently only know PHP and some C#) and have run into my first issue.
I am trying to call a class inside a switch, then use that defined variable after the switch. However, I get the error described in the title.
#include <iostream>
#include <string>
using namespace std;
class Hero {
protected:
int hHealth,hStamina,hExp;
string hName;
public:
void Create(string);
string GetName() {
return this->hName;
}
};
class Wizard:public Hero {
public:
void SetStats(string hName) {
this->hName = hName;
this->hHealth = 40;
this->hStamina = 80;
}
};
int main() {
string hName;
int hClass;
cout << "Welcome to Ryan's Dungeons & Dragons Adventure!\n\n";
cout << "Enter your Heroes name\n";
cout << "Name: ";
cin >> hName;
cout << hName << ", please select your class\n";
cout << "(1) The Wizard\n";
cout << "(2) The Warrior\n";
cout << "(3) The Rogue\n";
cout << "(4) The Priest\n";
cout << "Class: ";
cin >> hClass;
switch (hClass) {
case 1:
Wizard _hero;
break;
}
cout << _hero->GetName();
system("PAUSE");
return 0;
}
The error in question occurs on the line:
cout << _hero->getName();
where it says _hero is undefind.
_hero is defined only within the scope of that switch statement. You need to create objects in the same or higher up scope that you'll be using them.
One way you can get around this is define a pointer to Hero before the switch (initializing to null) and then set it to a value inside the switch. For instance:
Wizard *_hero = NULL;
switch (hClass) {
case 1:
_hero = new Wizard();
break;
}
}
if (_hero) {
cout << _hero->GetName();
}
You're also using the -> on a class value (as opposed to a pointer to one). Scope issues aside, you probably intended to write _hero.GetName(). Inside your class, -> is right however since this is a pointer to your object.
switch (hClass) {
case 1:
Wizard _hero;
break;
} // <-- _hero is deallocated at this point
cout << _hero->GetName();
The scope of _hero is limited to the switch statement.
I don't think that even works in C#... what you want is a pointer that's going to be initialized in the switch statement:
Hero* _hero = 0;
switch(hClass){
case 1: _hero = new Wizard;
break;
}
// use _hero ...
// at the end, delete it
delete _hero;
Though, you now most likely need a virtual destructor and virtual functions. Read up on them, they're a powerful OO feature. But you probably know about them from C#.
You said you know some C# and php, which I do not. I just want to know how would this have behaved in C#.
Creating an object inside some scope and using it outside the scope. Like: {int a;} a = 0;
In C++ its an issue.
switch (hClass) {
case 1:
Wizard _hero;
break;
}
//At this no _hero is present. _hero is out of its scope
The _hero object is restricted to the scope of that switch block. What you want is probably this:
Hero* _hero;
switch (hClass) {
case 1:
_hero = new Wizard();
break;
}
cout << _hero->GetName();