Do i need to delete newP (temp) after using it? - c++

I asked a question about a code and someone recommended i used newP to add a class to a vector, it works, but i dont fully understand the concept behind that way of doing.
string creaPersoFini("y");
vector<Personnage> tableauPerso; // Tableau de Personnage, pas de string
string nomPerso;
int nbPerso(3);
cout << "Trois personnages maximum, pour l'instant." << endl;
while(creaPersoFini!="n" && nbPerso < 4)
{
cout << "Entrez le nom du personnage : ";
cin >> nomPerso;
Personnage newP(nomPerso); // new temp person
tableauPerso.push_back(newP); // add the person
cout << "Voulez vous creer un autre personnage ? y/n ";
cin >> creaPersoFini;
}
Is this correct ? Do i need to delete the newP after adding it to the vector ? I know that if you create a pointer with new it is necessary to delete it afterward, is this what is happening here or not at all ?
I tried to look on internet and stackoverflow for an answer, but i only found parts of answers or quesitons/answers that are too complex for my current knowledge of C++.
If someone could explain to me in a simple way the difference between new/delete, newP and temporary using like these (or point me in a direction where i can find an answer) i'd be grateful !
Here is the link to the question where he recommended it, i used it because it works but since there was disagrement in the comments i'm not sure, and i'd like to be.

Related

Adding to a private variable not working

I'm currently learning c++ and trying to make a vending machine! I know my code is really bad and I am sorry about that.
I am trying to implement a bank and have the user take a loan from it, the only problem is that the bank is unable to add money to the user. Here's my code.
void Bank::askLoan() {
//ColaMachine object
ColaMachine cola;
bool loanGranted = false;
cout << string(100, '\n');
cout << "You do not have enough money!\n\n";
cout << "Would you like to take a loan?\n\n(1)-Yes\n(2)-No\n\n\n";
int choice;
cin >> choice;
switch (choice) {
case 1:
//Print the bank menu!
printBank();
while (loanGranted != true) {
cout << "Enter the amount to lend: $";
cin >> _loanValue;
//Test if _loanValue is less than or = to bankmoney, so they would scam the bank.
if (_loanValue <= _bankMoney) {
//Supposed to add money to the user.
cola.addMoney(_loanValue);
break;
}
else {
cout << "You entered too much! Try again..." << endl;
}
}
break;
case 2:
//User does not want to take a loan! Quit the game!
//Not implemented, yet.
break;
default:
cout << "Bad input! Please retry..." << endl;
}
}
If the amount entered was within the correct range it calls the addMoney() Func from ColaMachine class.
void ColaMachine::addMoney(int money) {
//This part doesnt seem to modify the actual value
//Whenever It goes back to the main game loop it doesnt change.
_money += money;
}
From what I understand += is the same as _money = _money + money;
What am I doing wrong here?
Full source on GitHub-
https://github.com/Rohukas/-LearningCPP
The problem is that you are creating new cola object inside askLoan() method which gets destroyed at the end of the function, so call to addMoney() method modifies state of that temporary cola object. One option is to provide cola object by pointer to the askLoan() method.
For example, in ColaMachine::chooseDrink() you would call bo.askLoan(this). this is pointer to the object from where you call bo.askLoan().
You would need to modify your askLoan() signature:
void askLoan(ColaMachine * cola) and remove ColaMachine cola; from askLoan() itself.
The problem is here
void Bank::askLoan() {
//ColaMachine object
ColaMachine cola;
bool loanGranted = false;
...
everytime you call Bank::askLoad you create a new ColaMachine, that's what the code above says. But the problem is that any changes to that ColaMachine are thrown away when you exit Bank::askLoan and the ColaMachine is destroyed. That's why the changes you make to the ColaMachine don't stick.
Instead you want to use same ColaMachine each time that you call Bank::askLoad. I can't say the best way to do that without seeing the rest of your code, but one way would be to pass ColaMachine as a reference parameter to Bank::askLoad
void Bank::askLoan(ColaMachine& cola) {
bool loanGranted = false;
...
Another way would be to make ColaMachine a class member variable of Bank
class Bank
{
...
void askLoan();
private:
ColaMachine cola;
};
Which is better? No idea. I think you need to read up on class design, and how the objects in your program should relate to each other. That seems to be the bit you're not getting at the moment.
=========================================================================
Having looked at your full code I can see that you make the same mistake in more than one place. In your main function you declare a Bank and a ColaMachine.
//ColaMachine Object
ColaMachine cola;
//Bank Object
Bank bank;
Those should be the only two Bank and ColaMachine objects you create, so this is wrong
void ColaMachine::chooseDrink() {
Bank bo;
...
bo.askLoan();
That Bank bo is a completely different bank from the one you declared in main. And like the previous code this Bank bo gets created and destroyed each time you call ColaMachine::chooseDrink.
I think that what you should be doing is passing the ColaMachine and Bank variables declared in main as reference parameters to the other parts of you code that need to use them. So (for instance)
void ColaMachine::chooseDrink(Bank& bank) {
...
bank.askLoan();
You have quite a lot of rewriting of this code to do.

C++ After Function Call and Function Completion, Game Crashes Entirely

I've been having an issue with a game I've been making in my C++ game programming class for school. For some reason, after calling a function which I'm using to manage the inventory based stuff, the function seems to complete and work (I think this because I put in cout commands at the end of it and they printed correctly, also the function runs twice in a row, and they both run), my entire game crashes and doesn't reach the next line. I tried commenting out all the code in the function and it still crashed. I commented out the function calls and it worked, but I still can't tell what is wrong with it. I'll put the code for the function and the section were I make the calls:
string inventoryFunction(int h, string ab)
{
if(h == 1)
inventory.push_back(ab);
else
if(h == 2)
{
for(int i=0; i < inventory.size(); i++)
{
if(inventory[i] == ab)
inventory[i].erase();
}
}
else
if(h == 3)
{
cout << inventory[0];
for(int i=1; i < inventory.size(); i++)
cout << ", " << inventory[i];
}
}
The function call:
if(answer.find("village") != string::npos)
{
cout << endl;
cout << "While looking around your village,\nyou found a stone sword and a cracked wooden shield!" << endl;
inventoryFunction(1, "stone sword");
inventoryFunction(1, "cracked wooden shield");
cout << "Would you like to set off on your adventure now?" << endl;
cin >> answer2;
capitalizeLower(answer2);
Not sure there's anything there likely to cause a crash, my advice would be to single-step your code in the debugger to see where it's falling over. It's quite possible the bug is somewhere totally different and it's just being exacerbated by the function calls modifying the vector.
That's the nature of bugs unfortunately, you can never really tell where they're actually coming from without looking closely :-)
However, there are a couple of issues with the code that I'd like to point out.
First, with regard to:
inventory[i].erase();
That doesn't do what you think it does. inventory[i] is the string inside your vector so it's simply erasing the string contents.
If you want to remove the string from the vector, you need something like:
inventory.erase (inventory.begin() + i);
Second, I'd tend to have three separate functions for addToInventory, removeFromInventory and listInventory.
It seems a little ... unintuitive ... to have to remember the magic values for h to achieve what you want to do, and there's no real commonality in the three use cases other than access to the inventory vector (and that's not really reason enough to combine them into the same member function).
On top of that, your function appears to be returning a string but you have no actual return statements and, in fact, none of the three use cases of your function require anything to be passed back.
The signature is better off as:
void inventoryFunction(int h, string ab)
In terms of the second and third points above, I'd probably start with something like:
void addToInventory (string item) {
inventory.push_back(ab);
}
void removeFromInventory (string item) {
for (int i = 0; i < inventory.size(); i++) {
if (inventory[i] == ab) {
inventory.erase (inventory.begin() + i);
break;
}
}
void listInventory () {
cout << inventory[0];
for (int i = 1; i < inventory.size(); i++)
cout << ", " << inventory[i];
}
You may also want to look into using iterators exclusively for the second and third functions rather than manually iterating over the collection with i.
It'll save you some code and be more "C++ic", a C++ version of the "Pythonic" concept, a meme that I hope will catch on and make me famous :-)
So by changing the inventoryFunction to a void function like #Retired Ninja said, the crash has stopped occurring and now the program is working great.
Also, #paxdiablo pointed out that I was using the inventory[i].erase() thing incorrectly, so thanks a bunch to him, because now I won't have to come back on here later to try to fix that :D
string inventoryFunction(int h, string ab)
should return a string but does not have any return statements. Of course it works, after you change it to a void function, which correctly does not return anything. Interesting is, that you are able co compile this code without an error - normally a compiler would show you this problem.

How to compare a vector to a map [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Okay so I have an inventory class that accesses a static vector from my base class MainShop. I also have a SwordShop class which inherits from MainShop. (Both Inventory and SwordShop are derived classes).
//SwordShop class
void SwordShop::Shop
{
//I have a setter function where it takes an integer and a string and adds its to my hashmap.
//Also have a getter function which has a for loop displaying my items in my map
this->setWeaponSoldier(1, "1) Meito Ichimonji\n +4 Damage\n 150Gold");
this->setWeaponSoldier(2, "2) Shusui\n +10 Damage\n 230Gold");
this->setWeaponSoldier(3, "3) Elixir\n +16 Damage\n 300Gold");
this->setWeaponSoldier(4, "4) Blade of scars\n +24 Damage\n 550Gold");
this->setWeaponSoldier(5, "5) Ragnarok\n +32 Damage\n 610Gold");
this->setWeaponSoldier(6, "6) Eternal Darkness\n +40 Damage\n 690Gold");
this->setWeaponSoldier(7, "7) Masamune\n +52 Damage\n 750Gold");
this->setWeaponSoldier(8, "8) Soul Calibur\n +60 Damage\n 900Gold");
}
//Function in my inventory class
void Inventory::DisplayInventory()
{
int choice;
cout << "\nWhat do you want to do?\n1) Check Status\n2) Equip Weapons\n";//Equip what is in your inventory
cin >> choice;
switch (choice)
{
case 1: this->DisplayStats();
break;
case 2:cout << WeaponInventory.size() << endl;//debug
if (!WeaponInventory.empty())//Make sure inventory is not empty
{
cout << "Your current Weapons are: \n";
for (unsigned int i = 0; i < WeaponInventory.size(); ++i)
cout << i+1 << ") " << WeaponInventory[i] << endl;//cout whats currently in my inventory
cout << "What item weapon would you like to equip?";
/***********Here is the problem*******************/
//how can I make the user choose the actual and correct item in the inventory?
//cin >> equipChoice;
//code goes here
}
else cout << "Error! You currently do not own any items\n";
break;
}
So for example lets say the user adds Meito Ichimonji into my WeaponInventory vector and then adds another one. How can I make the user have the ability to pick the right item? Im looking for something like this:
//PseudoCode
Displays my inventory with for loop
I have two items in it which user buys
1)Meito Ichimonji
and
2)Elixir
cout << "what would you like to equip?";
cin >> equipChoice
if (equipChoice == 1)//chooses whatever item is first
check to see what the attack that the weapon has and add it to my attack
attack += 20;//lets say the sword had 20 attack
else if (equipChoice == 2)//chooses whatever is second
do something else
etc...
Sorry if I have not explained it clearly, but I tried my best!
This is not really an issue of coding/code-design but rather a conceptual design issue. I would propose to start from a blank slate and formalise the design, possibly using a 'relational' perspective, even though you might not use an RDMS in an implementation (or some other formalism like UML) just to put some clear stakes in the ground. At least such model would give a clear view of the relationships between the various entities and help understanding what is needed in order to access/retrieve information from the model. Most likely the code will then be the least you'll have to worry about.

How to make an end of file output it's data?

this is my first time asking a question so forgive me if I stumble over anything. I have been working on a project for a suspension system for a car. I needed to make 4 functions for the displacement of the car and tire and the velocity of the car and tire. I feel that I structured the code well but it's simply not outputting the final product. The main purpose is to find the maximum of each function. I tried a lot to try and fix it but I can't seem to come up with a solution.
The main point is. I structured a program with four functions which the data file feeds with the information til it ends. When I try to run it nothing but the header is outputted. I am at a lost to how this is.
The data file has four groups ranging from car A to car D organized like so,
Spring Constant of tire, damp constant of dash-pot, mass of wheel, mass of car, start/end times, increment value
The functions themselves are sort of...Hard to swallow. So I would like to share some sections of code where I believe problems are.
Any help/hints/comments would be most appreciated.
csdatafiles>> total_readings;
csdatafiles >> car_name >> spring_constant_tire >> spring_constant_spring
>> damp_constant >> mass_of_tire >> mass_of_car
>> start_time_value >> end_time_value >> increment_time_value;
//Initialize max min
max_displacement_car=displacement_of_car;
max_displacement_tire=displacement_of_tire;
max_velocity_car=velocity_of_car;
max_velocity_tire=velocity_of_tire;
//Output Header
cout << "\nCar Name Max Tire Displace Max Tire Vel Max Car Displace Max Car Vel \n" << endl;
{
//recall functions
velocity_of_tire= old_new_tire_velocity (variables needed);
velocity_of_car=old_new_car_velocity (variables needed);
displacement_of_car= old_new_car_displacement (variables needed);
//check for max
if (displacement_of_car>max_displacement_car)
max_displacement_car=displacement_of_car;
if (displacement_of_tire>max_displacement_tire)
max_displacement_tire=displacement_of_car;
if (velocity_of_car>max_velocity_car)
max_velocity_car=velocity_of_car;
if (velocity_of_tire>max_velocity_tire)
max_velocity_tire=velocity_of_tire;
total_readings++;
//read rest of data
csdatafiles >> spring_constant_tire >> spring_constant_spring
>> damp_constant >> mass_of_tire >> mass_of_car
>> start_time_value >> end_time_value >> increment_time_value;
} while (!csdatafiles.eof());
//Output
cout << car_name << max_displacement_tire << max_velocity_tire << max_displacement_car << max_velocity_car;
Just going off of the code that you posted, it looks like you tried to put a do-while but forgot the do ...
Instead of
do {
//recall functions
//...
//check for max
//...
//read rest of data
//....
} while (!csdatafiles.eof());
You have
{
//recall functions
//...
//check for max
//...
//read rest of data
//....
} while (!csdatafiles.eof());
which is VERY different! Without the do, your code is equivalent to:
{
//recall functions
//...
//check for max
//...
//read rest of data
//....
}
while (!csdatafiles.eof()) {
;
}
As you can see, there is an infinite loop just before the last cout statement, so you never reach it.

How to keep alive an object for later use in another function?

I have a base class called Mijloc_transport and 2 derived classes called Masina and Tramvai. I must do an menu type program that can create different kind of objects from the derived classes and show them. I'm using the UPCASTING method and when I press 1 the if(tasta=="1") creates an object and I can see what type it is using: tabp[0]->show();. It seems that when the program enters again in the do loop (using the main label), the object created as 1 is destroyed and I can't see tabp[0]->show(); because the reference is deleted. What shall I do to keep the objects alive so I can put them in tabp?
Masina b(30);
p=&b;
tabp[i]=p;
so later I can display them....10x for your help
#include "include.hpp"
#include <ctype.h>
#include <cstdlib>
int main(void)
{
int i=0;
Mijloc_transport *tabp[MAX];
Mijloc_transport *p;
int tasta;
main:
do
{
//cout<<"\n\n\n\n\n";
cout<<endl<<"apasa orice tasta pentru a reveni la meniu "<<endl; getch();
system("cls");
cout<<"Tasteaza numarul optiunii dorite din meniu:"<<endl;
cout<<"1. creaza o masina cu 30 cai putere"<<endl; //create an Masina derived Oject
cout<<"2. creaza un tramvai cu 20 de locuri"<<endl;//create an Tramvai derived Oject
cout<<"3. afiseaza memoria"<<endl; //print the objects
cout<<"4. iesire"<<endl;
tasta=cin.get();
}
while(tasta!='1' && tasta!='2'&& tasta!='3'&& tasta!='4');
if(tasta=='1')
{
Masina b(30);
p=&b;
tabp[i]=p;
tabp[0]->show();
cout<<endl<<"apasa orice tasta pentru a reveni la meniu "<<endl;
getch();
//i++; //TREBUIE INCREMENTAT cand ai mai mult de un obiect
goto main;
}
if(tasta=='3')
{
//afiseaza elementele din memorie
//for(int j=0;j<=i;j++) //J<=i
//tabp[j]->show();
tabp[0]->show();
cout<<endl<<"apasa orice tasta pentru a reveni la meniu "<<endl;
getch();
return 1;
}
}
Instead of creating the object on the stack, like this:
Masina b(30);
you must create it dynamically, like this:
Masina *b = new Masina(30);
and furthermore, you should declare Masina *b somewhere outside the loop, so that it persists longer than the time you're in the loop.
Instead of:
Masina b(30);
p=&b;
tabp[i]=p;
do:
tabp[i] = new Masina(30);
and do not forget to do:
for ( unsigned int i = 0; i < MAX; ++i )
{
delete tabp[i];
}
When you no longer need tabp (before existing main).
Its hard to read your code, but based on your title I am guessing you want to create an object on the heap using the new keyword. This will allow you to create an object on the heap (as opposed to the stack) which will stay alive after a function exits, be warned you must clean up the memory associated with the allocation of new.
tabp[i] = new Masina(30);
but please... Each time you are using goto (especially like this) God kill a kitten.