Currently, I am working on a small project, called "Blood Donation". I used classes and Inheritance concepts there.
And When the new "blood donor" comes, I take its information, create the new object and store the address of the object into a "vector of pointers". But when I try to access the name of a person, I didn't get anything, I can access the other information...
Tired of finding, where is bug.....
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <unistd.h>
using namespace std;
int intCheck(string str){
for(int i=0;i<str.length();i ){
if (!(str[i] >= 48 && str[i] <= 57) ) return 0;
}
return stoi(str);
}
long long int longCheck(string str){
for(int i=0;i<str.length();i ){
if (!(str[i] >= 48 && str[i] <= 57) ) return 0;
}
return stoll(str);
}
class bloodBank{
private:
// ORDER : A B AB O A- B- AB- O-
static int totalBlood;
static int bloodGroupsRecords[8];
static int maleDonars;
static int femaleDonars;
static int totalDonars;
public:
static string bloodGroups[8];
static void display_totalBlood(){
cout << "\n Total Blood In The Blood Bank :: " << totalBlood << " ML " << "( " << totalBlood/(float)1000 << " ) Ltr.";
}
static void display_gender_donars(){
cout << "\n Male Donars : " << maleDonars ;
cout << "\n Female Donars : " << femaleDonars ;
}
static void display_group_donars(){
for (int i=0;i<8;i ){
cout << setw(5) << bloodGroups[i];
cout << " : " << bloodGroupsRecords[i];
}
}
static void increaseMD(){
maleDonars ;
}
static void increaseFD(){
femaleDonars ;
}
static void increaseTB(int blood){
totalBlood = blood;
}
static void addBloodToCategory(int bGroup,int bAmount){
bloodGroupsRecords[bGroup] = bAmount;
}
};
int bloodBank :: totalBlood=0;
int bloodBank :: bloodGroupsRecords[8] = {0};
int bloodBank :: maleDonars=0;
int bloodBank :: femaleDonars=0;
int bloodBank :: totalDonars = maleDonars femaleDonars;
string bloodBank :: bloodGroups[8] = {"A ","B ","AB ","O ","A-","B-","AB-","O-"};
class donate:public bloodBank{
private:
string name;
string village;
int bloodGroup;
int gender;
long long int phone;
int age;
int amount;
public:
void set_name(){
cout << "Enter Your Name : ";
getline(cin,name);
}
string get_name(){ cout << "Hello From get_name" ; return name;}
void set_village(){
cout << "Enter Your Village : ";
getline(cin,village);
}
string get_village(){ return village;}
int set_age(){
string s_age;
cout << "Enter Your Age : ";
getline(cin,s_age);
age = intCheck(s_age);
if (!(age >= 18 && age <=65)) { cout << "Enter The Age Properly & Age Must B/W 18 - 65 \n";set_age();}
return 1;
}
int get_age(){ return age;}
int set_phone(){
string s_phone;
cout << "Enter Your Phone : ";
getline(cin,s_phone);
phone = longCheck(s_phone);
if ((!phone) || (s_phone.length() > 12 || s_phone.length() < 6)) { cout << "Enter Your Phone Number Correctly \n";set_phone();}
return 1;
}
long long int get_phone(){ return phone;}
int set_bloodGroup(){
cout << "Choose Your Blood Group : \n";
cout << "1) A 2) B 3) AB 4) O \n";
cout << "5) A- 6) B- 7) AB- 8) O- \n";
string s_bg;
getline(cin,s_bg);
bloodGroup = intCheck(s_bg);
if(!((bloodGroup >= 1) && (bloodGroup <=8))){ cout << "Please Choose The Correct Blood Group \n"; set_bloodGroup();}
return 1;
}
int get_bloodGroup(){ return bloodGroup;}
int set_amount(){
string s_amount;
cout << "Enter Amount To Donate(ml) : ";
getline(cin,s_amount);
amount = intCheck(s_amount);
if (!(amount >= 100 && amount <= 500)){ cout << "Minimum Limit : 100 ML & Maximum Limit : 500 ML \n"; set_amount();}
return 1;
}
int get_amount(){ return amount;}
int set_gender(){
string s_gender;
cout << "Select Your Gender : \n1) Male \n2)Female \n";
getline(cin,s_gender);
gender = intCheck(s_gender);
if ((gender == -1) || (gender > 2) || (gender < 1)) { cout << "Please Select A Proper Number 1 or 2 \n";set_gender();}
else{
(gender == 1 )? gender = 1: gender = 2;
}
return 1;
}
int get_gender(){ return gender; }
void updateData(){
get_gender() == 1 ? increaseMD() : increaseFD();
increaseTB(get_amount());
addBloodToCategory(get_bloodGroup(),get_amount());
}
};
// --- BloodBank Database ---
vector<donate *> blood_bank_database;
// --- Donars Info ---
void donarsList(){
vector<donate *> :: iterator it = blood_bank_database.begin();
cout <<"normal";
cout << blood_bank_database[0]->get_gender();
cout << blood_bank_database[0]->get_name();
while(it != blood_bank_database.end()){
cout << "Name Of Donar : " << (*it)->get_name() << "Amount Of Blood Donated : " << (*it)->get_amount() ;
it ;
}
}
void menu(){
cout << "===== WELCOME TO BLOOD DONATION CAMP ====\n\n";
cout << "Use The Follwing Commands : \n";
cout << "1) Donate The Blood \n";
cout << "2) List Of Blood Donars \n";
cout << "3) Amount Of Blood Donated \n";
cout << "4) About Us \n";
cout << "5) EXIT \n\n";
}
void createDonar(){
donate d1;
d1.set_name();
d1.set_village();
d1.set_gender();
d1.set_age();
d1.set_phone();
d1.set_bloodGroup();
d1.set_amount();
d1.updateData();
blood_bank_database.push_back(&d1);
cout << "-- Thanks For Donating :) --\n";
}
void bloodDonated(){
cout << "------------------------------------\n";
bloodBank::display_totalBlood() ;
bloodBank::display_gender_donars() ;
bloodBank::display_group_donars() ;
cout << "\n------------------------------------\n";
}
void aboutUs(){
cout << "-----------------------------------------------------\n";
cout << "\n _-_-_ | OPEN-EYES BLOOD CAMP | _-_-_\n";
cout << "\n ! Donate Blood, Save Life ! \n";
cout << "\n\n-- Near Grand Park, NewWay Street, CALIFORNIA --\n\n";
cout << "-----------------------------------------------------\n";
}
int main(){
createDonar();
// donarsList();
bloodDonated();
auto it = blood_bank_database.begin();
cout << (*it)->get_gender();
cout << (*it)->get_name();
return 0;
}
CodePudding user response:
void createDonar(){
donate d1;
The d1
object is declared in automatic scope in this function. This means that d1
gets destroyed when this function returns. It will be gone. It will be no more. It will cease to exist. It will become an ex-object. When you declare non-static
variables and objects in a function that's what happens to them when the function returns, that's how C works.
blood_bank_database.push_back(&d1);
The same function then pushes a pointer to d
into this std::vector
, and then returns. So, what has been accomplished here? This is what was accomplished here, the end result: the vector gets filled up with pointers to destroyed objects, and all subsequent use of those pointers becomes undefined behavior.
The general name for this kind of a problem is called "pointless use of pointers". This is because nothing of value gets accomplished by using pointers, when none are needed. blood_bank_database
can simply be a
vector<donate> blood_bank_database;
and the rest of the code adjusted accordingly. The end result will be much simpler, and less error-prone.
CodePudding user response:
I Also Can make the donate *d1 = new donate;
in createdonor()
function, so that dynamic object will be created and object will not be destroyed, after ending the function...