So I'm creating this for an assignment in Uni.
It has to use a class structure with 'Vehicle' as the main class, and two classes which inherit some functions from it; 'Car' and 'Lorry'.
So I've created my class structure successfully (I think) but I need to create a basic UI for this, bearing it mind it is a console application, I am just creating a basic menu using switches.
How ever, in my "getDetails" section, it is only grabbing the 'Vehicle::getDetails' when it should be also getting the 'Car/lorry::getdetails', as well as the vehicle details.
Any ideas what could be causing that?
First post here, so sorry if my post is bad :(.
Thanks!
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class vehicle {
public:
string manufacturer;
int year;
string regnum;
void getDetails() {
cout << "Please enter the details for your vehicle"<< endl;
cout << "Please enter the manufacturer of your vehicle: "<< endl;
cin >> manufacturer;
cout << "Please enter the year of your vehicle's manufacture: "<< endl;
cin >> year;
cout << "Please enter your vehicle's registration number: "<< endl;
cin >> regnum;
}
void printDetails() {
cout << "Your vehicle's details are as follows: " << endl;
cout << "Your Vehicle's manufacturer is " << manufacturer << endl;
cout << "Your Vehicle's year of manufacture is " << year << endl;
cout << "Your Vehicle's registration number is " << regnum << endl;
}
void saveDetails() {
ofstream vehiclefile;
vehiclefile.open ("vehicle.txt");
vehiclefile << "***Your Vehicle's Details***" << endl;
vehiclefile << "Manufacturer:" << manufacturer << endl;
vehiclefile << "Year of Manufacture:" << year << endl;
vehiclefile << "Registration Number: " << regnum << endl;
vehiclefile.close();
}
void openVehicleDetails() {
}
};
class car : public vehicle{
public:
int numpassengers;
string cartype;
void getDetails() {
vehicle::getDetails();
cout << "Please enter the number of maximum passengers your car can hold: "<< endl;
cin >> numpassengers;
cout << "Please enter the car body type: "<< endl;
cin >> cartype;
cout << "Thank your for your details"<< endl;
}
void printDetails() {
vehicle::printDetails();
cout << "Your car's maximum passengers is: " << numpassengers << endl;
cout << "The body type of your car is: " << cartype << endl;
}
void saveDetails() {
vehicle::saveDetails();
ofstream vehiclefile;
vehiclefile.open ("vehicle.txt");
vehiclefile << "Car or Lorry: Car" << endl;
vehiclefile << "Number of passengers: " << numpassengers << endl;
vehiclefile << "Type of car: " << cartype << endl;
vehiclefile.close();
}
};
class lorry : public vehicle{
public:
double tonnage;
string bodtype;
void getDetails() {
vehicle::getDetails();
cout << "Please enter the gross weight of your Lorry: "<< endl;
cin >> tonnage;
cout << "Please enter the body type of your Lorry: "<< endl;
cin >> bodtype;
cout << "Thank your for your details"<< endl;
}
void printDetails() {
vehicle::printDetails();
cout << "Your lorry's details are as follows: " << endl;
cout << "Your lorry's maximum weight is: " << tonnage << endl;
cout << "The body type of your lorry is: " << bodtype << endl;
}
void saveDetails() {
vehicle::saveDetails();
ofstream vehiclefile;
vehiclefile.open ("vehicle.txt");
vehiclefile << "Car or Lorry: Lorry" << endl;
vehiclefile << "Maximum weight: " << tonnage << endl;
vehiclefile << "Body type: " << bodtype << endl;
vehiclefile.close();
}
};
int main () {
int flag = 0;
char choice;
int ifchoice;
vehicle*v;
while (flag == 0){
cout << "***Main Menu***" << endl; //Menu to allow ease of access within the program.
cout << "Select by letter:" << endl;
cout << "1 - Add new entry" << endl;
cout << "2 - Show entry" << endl;
cout << "3 - Save entry" << endl;
cout << "4 - Open saved document" << endl;
cout << "5 - Delete entry" << endl;
cin >> choice;
switch(choice) {
case '1':
cout << "Is your vehicle a Car or a Lorry? " << endl;
cout << "Press '1' for Car " << endl;
cout << "Press '2' for Lorry " << endl;
cin >> ifchoice;
if (ifchoice == 1)
{
v = new car();
}
if (ifchoice == 2)
{
v = new lorry();
}
v->getDetails();
break;
case '2':
v -> printDetails();
break;
case '3':
v -> saveDetails();
break;
}
}
}
The key point of the exercise is to make the void getDetails() method virtual in the base vehicle class.
(I'd also define a virtual destructor in the vehicle class as well, as good coding practice.)
class vehicle {
public:
string manufacturer;
int year;
string regnum;
// Make this virtual
virtual void getDetails() {
...
In the derived classes you may want to use the new C++11 override specifier as well.
In c++, if you want a function to be overridable by a deriving class, you label it virtual, i.e.:
class vehicle {
...
virtual void getDetails()
{
...
}
...
}
Related
(I'm just a guy trying to start programming so don't be too harsh, English is not my main language too)
I was trying to make a simple program about storing book into a library (with class since I started learning them) and the array won't show up in a different case other than the one in which I initialized it, the IDE doesn't show up any error too
Code:
#include <iostream>
using namespace std;
class MainMenu {
public:
int choice, ID, IDC;
string Name[500];
string Genre[500];
string Book[500];
void Menu() {
cout << "choose an action:" << endl;
cout << "1)\tadd a book\n2)\tsee my book" << endl;
cin >> choice;
switch (choice) {
case 1:
cout << "ID:" << endl;
cin >> ID;
cout << "name:" << endl;
cin >> Name[ID];
cout << "Genre" << endl;
cin >> Genre[ID];
cout << "> " << endl;
cin >> Book[ID];
cout << "<" << endl;
cout << "book successfully registered" << endl;
// assign a value about the book (name and genre) in each array stored
// with the id
break;
case 2:
cout << "ID?" << endl;
cin >> IDC; // IDC stands for ID Check, if ID == IDC then it should show
// the specs of the book + its content
cout << Name[IDC] << endl
<< Genre[IDC] << endl
<< "--> " << Book[IDC] << endl
<< endl;
break;
} // Switch
} // Menu
}; // Class
int main() {
int i = 0;
while (i == 0) // creating a loop to keep showing the menu without the end of
// the program
{
MainMenu giorgio;
giorgio.Menu(); // summoning menu
}
}
When you create a Object, all atributes are initialized, as a result, you create a emptiy arrays of your Object for each iteration, you can resolve this whit this code:
#include <iostream>
using namespace std;
class MainMenu {
public:
int choice, ID, IDC;
string Name[500];
string Genre[500];
string Book[500];
void Menu() {
cout << "choose an action:" << endl;
cout << "1)\tadd a book\n2)\tsee my book" << endl;
cin >> choice;
switch (choice) {
case 1:
cout << "ID:" << endl;
cin >> ID;
cout << "name:" << endl;
cin >> Name[ID];
cout << "Genre" << endl;
cin >> Genre[ID];
cout << "> " << endl;
cin >> Book[ID];
cout << "<" << endl;
cout << "book succesfully registered" << endl;
break;
case 2:
cout << "ID?" << endl;
cin >> IDC;
cout << Name[IDC] << endl
<< Genre[IDC] << endl
<< "--> " << Book[IDC] << endl
<< endl;
break;
}
}
};
int main() {
int i = 0;
MainMenu giorgio;
while (i == 0)
{
giorgio.Menu(); // summoning menu
}
}
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
class Book
{
public:
char ISBN [5];
char Title [20];
char authorName [20];
char Price [10];
char Year [10];
char NumOfPages [10];
char delimiter = ',';
};
void AddBook ()
{
fstream file;
file.open("Records.txt", ios::out|ios::app);
Book b;
cout << "Enter ISBN: " << endl;
cin>>b.ISBN;
cin.ignore();
cout << "Enter Title: " << endl;
cin.getline(b.Title,sizeof(b.Title));
cout << "Enter Author's Name: " << endl;
cin.getline(b.authorName , sizeof(b.authorName));
cout << "Enter Price: " << endl;
cin.getline(b.Price,sizeof(b.Price));
cout << "Enter Year: " << endl;
cin.getline(b.Year,10);
cout << "Enter Number Of Pages: " << endl;
cin.getline(b.NumOfPages , sizeof(b.NumOfPages));
cin.ignore();
file.write(reinterpret_cast<char*>(&b), sizeof(b));
file.write(reinterpret_cast<char*>(&b.delimiter), sizeof(b.delimiter));
file.close();
}
void DeleteBook ()
{
}
void UpdateBook ()
{
}
void PrintBook ()
{
}
void PrintAll ()
{
ifstream file;
file.open("Records.txt", ios::in);
Book b;
while (!file.eof())
{
cout << "ISBN :" << b.ISBN <<endl;
cout << "Title :" << b.Title <<endl;
cout << "Author's Name :" << b.authorName <<endl;
cout << "Price :" << b.Price <<endl;
cout << "Year :" << b.Year <<endl;
cout << "Number of Pages "<< b.NumOfPages <<endl;
file.read(reinterpret_cast <char*> (&b), sizeof(b));
}
file.close();
}
int main()
{
int choice;
do
{
cout << "The Menu for Book Store" << endl;
cout << "1. Add Book: " << endl;
cout << "2. Delete Book: " << endl;
cout << "3. Update Book:" << endl;
cout << "4. print a Book:" <<endl;
cout << "5. print all Books " << endl;
cout << "6. Exit the program "<<endl;
cout << "Enter your choice here "<<endl;
cin >> choice;
switch (choice)
{
case 1:
AddBook();
break;
case 2:
DeleteBook();
break;
case 3:
UpdateBook();
break;
case 4:
PrintBook();
break;
case 5:
PrintAll();
break;
default:
cout << "Invalid Selection" << endl;
}
}
while
(choice != 6);
return 0;
}
The output looks strange in file and the output is being outputted twice on in strange chars and the other is good but ISBN is attached to title i need a solution please how i can fix it as it's not obvious where's the logical error here for me
Output
ISBN :
╞3╧v`≡o F╙v└²a
Title :
≡o F╙v└²a
Author's Name
:
Price :
F╙
Year :
oÇ≡o╘≡o
Number of Pages
ISBN :12345Jungle House
Title :Jungle House
Author's Name :ASad asad
Price :240
Year :2019
Number of Pages 300
You have many problems with the code you show, but the reason for the seemingly garbage output is that your printAll function you print the data in the Book object b before you read anything into it.
That means the object b isn't initialized yet, and will contain indeterminate data (which might seem like random or garbage). Using such values in any way leads to undefined behavior.
This is part of my project codes.
About the struct customer that I did, from welcomeScreen function I call the getInfo function for user to input the details (as you can see) and then return back the value to welcomeScreen function for output.
I can compile the codes, but the problem is there is no output for all the details after I input it (just blank)? Sorry if this is a dumb question cause im still a student.
struct customer
{
string name;
string email;
int number;
};
void welcomeScreen(); //prototype
void getInfo(struct customer cust); //prototype
void welcomeScreen()
{
struct customer cust; // struct declaration
const int SIZE=5;
system("CLS");
cout << setfill ('-') << setw (55) << "-" << endl;
cout << "\tWelcome to Computer Hardware Shop" << endl;
cout << setfill ('-') << setw (55) << "-" << endl;
cout << endl << "Type of hardwares that we sell:" << endl;
string item[SIZE]={"Monitor","CPU","RAM","Solid-State Drive","Graphic Card"};
for(int i=0;i<SIZE;i++)
cout << "\t" << i+1 << ". " << item[i] << endl;
getInfo(cust);
cout << endl;
cout << fixed << showpoint << setprecision (2);
cout << "Name: "<< cust.name << endl; // struct output
cout << "Email: "<< cust.email << endl;
cout << "Phone Number: " << cust.number << endl;
cout << endl;
}
void getInfo(struct customer cust)
{
cout << endl << "Enter name: ";
cin >> cust.name;
cout << "Enter email: ";
cin >> cust.email;
cout << "Enter phone number: ";
cin >> cust.number;
}
You probably want to pass a pointer or a reference, in this case recommend a reference because it means fewer changes to your code:
void getInfo(struct customer &cust); //prototype
Remember to change your function parameter as well.
I created this simple program to practice working with classes. I'm certain there are some errors with the way I used the class, but I'm just beginning to learn about them, so I haven't learned all of the conventions and etiquette. My main question is, can Xcode have functions that are buffered and other functions that are non-buffered? I'd like my function void InputValuesAndDisplayTotals(); to be buffered and my function void ManuallyAddCoinsAndDisplayTotals(); to be non-buffered (basically, hit a key and the character is instantly processed without using the enter key). Is this possible? Thanks in advanced.
#include <iostream>
#include <iomanip>
using namespace std;
class Coin
{
private:
const float PENNYVALUE = 0.01;
const float NICKELVALUE = 0.05;
const float DIMEVALUE = 0.10;
const float QUARTERVALUE = 0.25;
int PennyInput=0;
int NickelInput=0;
int DimeInput=0;
int QuarterInput=0;
public:
void InputValuesAndDisplayTotals();
void ManuallyAddCoinsAndDisplayTotals();
void Total();
};
int main()
{
int Choice;
Coin Count;
cout << "1 to enter total coin counts, 2 to manually count coins: ";
cin >> Choice;
if (Choice==1)
{
Count.InputValuesAndDisplayTotals();
Count.Total();
}
else
{
Count.ManuallyAddCoinsAndDisplayTotals();
}
cout << endl;
}
void Coin::InputValuesAndDisplayTotals()
{
cout << fixed << setprecision(2) << endl;
cout << "Input penny count: ";
cin >> PennyInput;
cout << "Total penny value: $" << PENNYVALUE*PennyInput;
Total();
cout << endl;
cout << "Input nickel count: ";
cin >> NickelInput;
cout << "Total nickel value: $" << NICKELVALUE*NickelInput;
Total();
cout << endl;
cout << "Input dime count: ";
cin >> DimeInput;
cout << "Total dime value: $" << DIMEVALUE*DimeInput;
Total();
cout << endl;
cout << "Input quarter count: ";
cin >> QuarterInput;
cout << "Total quarter value: $" << QUARTERVALUE*QuarterInput;
Total();
}
void Coin::ManuallyAddCoinsAndDisplayTotals()
{
char Choice2;
cout << "\n'1' for penny,\n'2' for nickel,\n'3' for dime,\n'4' for quarter,\n'q' to quit\n";
do
{
cout << "\nInput: ";
cin >> Choice2;
if (Choice2=='1')
++PennyInput;
if (Choice2=='2')
++NickelInput;
if (Choice2=='3')
++DimeInput;
if (Choice2=='4')
++QuarterInput;
cout << endl;
cout << "Pennies: " << PennyInput << endl;
cout << "Nickels: " << NickelInput << endl;
cout << "Dimes: " << DimeInput << endl;
cout << "Quarters: " << QuarterInput << endl;
Total();
}
while (Choice2!='q' && Choice2!='Q');
}
void Coin::Total()
{
cout << "\nTotal amount: $";
cout << fixed << setprecision(2) << (PENNYVALUE*PennyInput)+(NICKELVALUE*NickelInput)+(DIMEVALUE*DimeInput)+(QUARTERVALUE*QuarterInput);
cout << "\n";
}
I'm working on an assignment in my first semester of C++ and I just can't figure out working syntax for it. I need to pass a struct as a parameter to a class function using a pointer. This code I've copied is my best attempt, and it will compile but it crashes when it asks for the first name. When I try variations in the syntax, I get errors about incomplete struct, undefined variables (warrior was or invalid operators. What am I doing wrong?
#include <iostream>
using namespace std;
class StarWars
{
public:
int totalNumber;
struct data_clone
{
int ID, timeCounter;
string name;
};
data_clone *warrior;
void createClone()
{
cout << "How many clone warriors do you want to create in total?" << endl;
cin >> totalNumber;
}
void input(struct data_clone *pointer, int total)
{
for(int i = 1; i <= total; i++)
{
cout << "For warrior number " << i << ":" << endl;
cout << "What is the warrior's name?" << endl;
cin >> pointer[i].name;
cout << "What is the warrior's ID number?" << endl;
cin >> pointer[i].ID;
cout << "What is the warrior's time counter?" << endl;
cin >> pointer[i].timeCounter;
}
}
void lifeSpan(struct data_clone *pointer, int total)
{
for(int i = 1; i <= total; i++)
{
cout << "Warrior number " << pointer[i].name << ": " << endl;
while(pointer[i].timeCounter > 0)
{
cout << "Warrior name: " << pointer[i].name << endl;
cout << "Warrior ID number: " << pointer[i].ID << endl;
cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
cout << "Clone is alive." << endl;
pointer[i].timeCounter--;
}
cout << "Warrior name: " << pointer[i].name << endl;
cout << "Warrior ID number: " << pointer[i].ID << endl;
cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
cout << "Clone is dead." << endl;
}
}
};
int main(void)
{
StarWars clones;
clones.createClone();
clones.input(clones.warrior, clones.totalNumber);
clones.lifeSpan(clones.warrior, clones.totalNumber);
}
You don't initialise the memory warrior points to, so you're working with uninitiailised memory - always a bad thing. There's two things to keep in mind here:
When working with pointers, always initialise the memory behind them first. Prefer using RAII concepts like std::unique_ptr / std::shared_ptr
void DoStuff(Widget* w);
std::unique_ptr<Widget> pw = std::make_unique<Widget>();
DoStuff(w.get());
When working with normal variables, use the dereference / reference operators to take a pointer to the variable.
void DoStuff(Widget* w);
Widget widget;
DoStuff(&w);
struct data_clone
{
int ID, timeCounter;
string name;
};
class StarWars
{
private:
data_clone *warrior;
int totalNumber;
public:
StarWars()
{
}
~StarWars()
{
delete[] warrior; // clean up
}
void createClone();
void input();
void lifeSpan();
};
void StarWars::createClone()
{
cout << "How many clone warriors do you want to create in total?" << endl;
cin >> totalNumber;
// construct structure baased on input
warrior = new data_clone[totalNumber];
}
void StarWars::input()
{
for(int i = 0; i < totalNumber; i++)
{
cout << "For warrior number " << i+1 << ":" << endl;
cout << "What is the warrior's name?" << endl;
cin >> warrior[i].name;
cout << "What is the warrior's ID number?" << endl;
cin >> warrior[i].ID;
cout << "What is the warrior's time counter?" << endl;
cin >> warrior[i].timeCounter;
}
}
void StarWars::lifeSpan()
{
std::cout<<"**********Print data**********\n";
for(int i = 0; i < totalNumber; i++)
{
cout << "Warrior number " << warrior[i].name << ": " << endl;
while(warrior[i].timeCounter > 0)
{
cout << "Warrior name: " << warrior[i].name << endl;
cout << "Warrior ID number: " << warrior[i].ID << endl;
cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
cout << "Clone is alive." << endl;
warrior[i].timeCounter--;
}
cout << "Warrior name: " << warrior[i].name << endl;
cout << "Warrior ID number: " << warrior[i].ID << endl;
cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
cout << "Clone is dead." << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
StarWars clones;
clones.createClone();
clones.input();
clones.lifeSpan();
return 0;
}
You never created your clones, you only read how many there should be.
Allocate space for them:
void createClone()
{
cout << "How many clone warriors do you want to create in total?" << endl;
cin >> totalNumber;
warrior = new data_clone[totalNumber];
}
Your array indexes are also off - an array of size N is indexed from 0 to N - 1.
But the more common way of handling this is to pass the amount to the constructor and let the object handle its own members:
class StarWars
{
public:
StarWars(int clones)
: totalNumber(clones),
warrior(new data_clone[clones])
{
}
void input()
{
for(int i = 0; i < totalNumber; i++)
{
cout << "For warrior number " << i << ":" << endl;
cout << "What is the warrior's name?" << endl;
cin >> warrior[i].name;
cout << "What is the warrior's ID number?" << endl;
cin >> warrior[i].ID;
cout << "What is the warrior's time counter?" << endl;
cin >> warrior[i].timeCounter;
}
}
void lifeSpan()
{
for(int i = 0; i < totalNumber; i++)
{
cout << "Warrior number " << i << ": " << endl;
while(warrior[i].timeCounter > 0)
{
cout << "Warrior name: " << warrior[i].name << endl;
cout << "Warrior ID number: " << warrior[i].ID << endl;
cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
cout << "Clone is alive." << endl;
warrior[i].timeCounter--;
}
cout << "Warrior name: " << warrior[i].name << endl;
cout << "Warrior ID number: " << warrior[i].ID << endl;
cout << "Warrior time counter: " << warrior[i].timeCounter << endl;
cout << "Clone is dead." << endl;
}
}
private:
int totalNumber;
struct data_clone
{
int ID, timeCounter;
string name;
};
data_clone *warrior;
};
int main()
{
int number = 0;
cout << "How many clone warriors do you want to create in total?" << endl;
cin >> number;
StarWars clones(number);
clones.input();
clones.lifeSpan();
}
Note that you need to handle the destructor, the copy constructor, and the assignment operator properly as well (left as an exercise).
class StarWars
{
private:
struct data_clone
{
int ID, timeCounter;
string name;
};
public:
StarWars()
{
warrior = new data_clone[4];
}
~StarWars()
{
delete[] warrior;
}
int totalNumber;
data_clone *warrior;
void createClone()
{
cout << "How many clone warriors do you want to create in total?" << endl;
cin >> totalNumber;
}
void input(struct data_clone *pointer, int total)
{
for(int i = 0; i < total; i++)
{
cout << "For warrior number " << i << ":" << endl;
cout << "What is the warrior's name?" << endl;
cin >> pointer[i].name;
cout << "What is the warrior's ID number?" << endl;
cin >> pointer[i].ID;
cout << "What is the warrior's time counter?" << endl;
cin >> pointer[i].timeCounter;
}
}
void lifeSpan(struct data_clone *pointer, int total)
{
for(int i = 0; i < total; i++)
{
cout << "Warrior number " << pointer[i].name << ": " << endl;
while(pointer[i].timeCounter > 0)
{
cout << "Warrior name: " << pointer[i].name << endl;
cout << "Warrior ID number: " << pointer[i].ID << endl;
cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
cout << "Clone is alive." << endl;
pointer[i].timeCounter--;
}
cout << "Warrior name: " << pointer[i].name << endl;
cout << "Warrior ID number: " << pointer[i].ID << endl;
cout << "Warrior time counter: " << pointer[i].timeCounter << endl;
cout << "Clone is dead." << endl;
}
}
};
Note: I just hardcoded it which is not the correct way, it force you to enter only 4 tyeps of dataclone
"warrior = new data_clone[4];"
you will at least get your result