consider this is my code:
void SportShoe::AddSportShoe() {
SportShoe MySepatu[SIZE];
int numOfShoe = 0;
nodeSport *tempShoe1;
while (numOfShoe < SIZE){
cout << "Please enter the Shoe ID : (eg. 23210) " << endl;
cin >> SportShoe::MySepatu[numOfShoe].ShoeID;
cout << "Please enter the Shoe Brand: (eg. Adidas) " << endl;
cin.sync();
cin.getline(SportShoe::MySepatu[numOfShoe].BrandShoe,100);
cout << "Please enter the price of the Shoe : (eg. RM123.22) " << endl;
cin >> SportShoe::MySepatu[numOfShoe].PriceShoe;
cout << endl;
//passing the value from 'MySepatu' to 'tempShoe'
SportShoe::MySepatu[numOfShoe].ShoeID = (tempShoe1->ShoeIDList);
SportShoe::MySepatu[numOfShoe].BrandShoe[100] = (tempShoe1->BrandShoeList[100]);
SportShoe::MySepatu[numOfShoe].PriceShoe = (tempShoe1->PriceShoeList);
//i do some dummy to see what stored in tempShoe1
cout << "ID =>> " << tempShoe1->ShoeIDList << endl;
cout << "Brand =>> " << tempShoe1->BrandShoeList << endl;
cout << "Price =>> " << tempShoe1->PriceShoeList << endl;
}
while (numOfShoe >= SIZE-1){
cout << ">> List is already full !! <<";
system("PAUSE");
MenuSportShoe();
}
}
The code can be run as usual and doesn't show any error on the compiler. But, when it reach to the 'cout' area it'll print out something like an address of a pointer. Not the value.
Actually i think i use the wrong method to pass the value. I don't have idea on how to assign them.
//Here my class declaration
class SportShoe {
private:
struct nodeSport {
int ShoeIDList;
char BrandShoeList[100];
float PriceShoeList;
nodeSport *last;
};
nodeSport *first = NULL;
struct Shoe {
int ShoeID;
char BrandShoe[100];
float PriceShoe;
}MySepatu[SIZE];
public:
void AddSportShoe();
};
*i use array because i want to set a limit of the node. The linked list is useful for the other function like 'delete' , 'display', & etc.
Have any opinion to solve this and upgrade my code?
Don't use c strings, use std::string. Don't use arrays, use std::array or std::vector or a similar container. This will sure fix your problem.
class SportShoe {
private:
struct nodeSport {
int ShoeIDList;
std::string BrandShoeList;
float PriceShoeList;
nodeSport *last;
};
nodeSport *first = NULL;
struct Shoe {
int ShoeID;
std::string BrandShoe;
float PriceShoe;
};
std::array<Shoe, SIZE> MySepatu;
public:
void AddSportShoe();
};
void SportShoe::AddSportShoe() {
std::array<SportShoe, SIZE> MySepatu;
int numOfShoe = 0;
nodeSport *tempShoe1;
while (numOfShoe < SIZE){
cout << "Please enter the Shoe ID : (eg. 23210) " << endl;
cin >> SportShoe::MySepatu[numOfShoe].ShoeID;
cout << "Please enter the Shoe Brand: (eg. Adidas) " << endl;
cin.sync();
std::getline(cin, SportShoe::MySepatu[numOfShoe].BrandShoe);
cout << "Please enter the price of the Shoe : (eg. RM123.22) " << endl;
cin >> SportShoe::MySepatu[numOfShoe].PriceShoe;
cout << endl;
//passing the value from 'MySepatu' to 'tempShoe'
SportShoe::MySepatu[numOfShoe].ShoeID = tempShoe1->ShoeIDList;
SportShoe::MySepatu[numOfShoe].BrandShoe = tempShoe1->BrandShoeList;
SportShoe::MySepatu[numOfShoe].PriceShoe = tempShoe1->PriceShoeList;
//i do some dummy to see what stored in tempShoe1
cout << "ID =>> " << tempShoe1->ShoeIDList << endl;
cout << "Brand =>> " << tempShoe1->BrandShoeList << endl;
cout << "Price =>> " << tempShoe1->PriceShoeList << endl;
}
while (numOfShoe >= SIZE-1){
cout << ">> List is already full !! <<";
system("PAUSE");
MenuSportShoe();
}
}
Related
I was given a task to write an example of derived class. But In my program, something strange is happening with the roll numbers.
Also, when this program is compiled in g++.
When I used char [] and gets() to store the strings and input values into them, it didn't allow me to enter the value for collname.
When I use string and cin, I get some strange values while asking for marks.(Check the attached image).
#include<iostream>
#include<conio.h>
using namespace std;
class uni
{
private:
int rollno[100], i, flag;
int intermarks[100];;
int theorymarks[100];
void settheorymarks();
protected:
int numstud;
void setintermarks();
void issurno();
public:
void prepres();
void showres(string collname);
};
class college : public uni
{
private:
string collname;
public:
college(int N)
{
numstud = N;
issurno();
}
void enter_marks();
void disp();
};
void uni::issurno()
{
for (i = 0; i < numstud; i++)
rollno[i] = 1024+i;
cout << "Roll numbers issued!" << endl;
}
void uni::settheorymarks()
{
cout << "Enter theory marks for: " << endl ;
for(i = 0; i < numstud; i++)
{
cout << i+1 << ".) Roll number: " << rollno << " : ";
cin >> theorymarks[i];
}
cout << endl << endl << "Theory marks recorded!" << endl;
}
void uni::setintermarks()
{
cout << "Enter inter marks for: " << endl ;
for(i = 0; i < numstud; i++)
{
cout << i+1 << ".) Roll number: " << rollno << " : ";
cin >> intermarks[i];
}
cout << endl << endl << "Internal marks recorded!" << endl;
}
void uni::prepres()
{
settheorymarks();
}
void uni::showres(string colnam)
{
cout << "College: " << colnam << endl;
cout << "__________________________Result___________________________" << endl;
cout << "s. No.\tRoll no\tInternal\tTheory" << endl;
for(i = 0; i < numstud; i++)
cout << i+1 << "\t" << rollno[i] << '\t' << intermarks[i] << "\t" << theorymarks[i] << endl;
cout << endl << "End of result!" << endl;
}
void college::disp()
{
showres(collname);
}
void college::enter_marks()
{
cout << "Enter the college name: ";
cin >> collname;
setintermarks();
prepres();
}
int main()
{
int n;
cout << "Enter number of stufents: ";
cin >> n;
college c(n);
c.enter_marks();
c.disp();
return 0;
}
I feel that I've made a stupid mistake somewhere.
PS: In school, I was forced to use turbo C++ (One of the oldest compilers).
You just forget the [i] after rollno in the two lines like:
cout << i+1 << ".) Roll number: " << rollno[i] << " : ";
There are a few other things I would ask you to improve if I was your supervisor/teacher:
always use expressive variable and method names. Avoid any abbreviations.
why is there the arbitray offset of 1024 in rollno? If this is just "obfuscation" remove it...
Unclear: why is setintermarks called inside enter_marks but settheorymarks in prepres ?
typo in "stufents"
#pragma once
#ifndef SDDS_GIFT_H
#define SDDS_GIFT_H
#include <iostream>
namespace sdds
{
const int MAX_DESC = 15;
const double MAX_PRICE = 999.999;
const int MAX_WRAP = 20;
struct Gift
{
char m_description[MAX_DESC];
double m_price;
int m_units;
int m_wrapLayers;
struct Wrapping* m_wrap;
};
struct Wrapping
{
char* m_pattern;
};
void gifting(char*);
void gifting(double&);
void gifting(int&);
bool wrap(Gift& theGift);
bool unwrap(Gift& theGift);
void gifting(Gift& theGift);
void display(const Gift& theGift);
}
#endif
<pre><code>
#include <iostream>
#include "Gift.h"
using namespace std;
namespace sdds
{
void gifting(char* m_description) // sending info
{
cout << "Enter gift description: ";
cin.width(MAX_DESC + 1);
cin >> m_description;
}
void gifting(double& m_price)
{
cout << "Enter gift price: ";
cin >> m_price;
while (m_price > MAX_PRICE || m_price < 0)
{
cout << "Gift price must be between 0 and " << MAX_PRICE << std::endl;
cout << "Enter gift price: ";
cin >> m_price;
}
}
void gifting(int& m_units)// gifting function
{
cout << "Enter gift units: ";
cin >> m_units;
while (m_units < 1)
{
cout << "Gift units must be at least 1" << std::endl;
cout << "Enter gift units: ";
cin >> m_units;
};
}
bool wrap(Gift& m_wrap) {
if (m_wrap.m_wrapLayers > 0) {
cout << "Gift is already wrapped!" << endl;
return false;
}
else {
cout << "Wrapping gifts..." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
while (m_wrap.m_wrapLayers < 1) {
cout << "Layers at minimum must be 1, try again." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
}
int i = 0;
m_wrap.m_wrap = new Wrapping[MAX_WRAP + 1];
for (i = 0; i < m_wrap.m_wrapLayers; i++) {
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> m_wrap.m_wrap->m_pattern;
} // I put struct in a structure
return true;
}
delete[]m_wrap.m_wrap;
m_wrap.m_wrap = nullptr;
}
bool unwrap(Gift& g_unwrap) // unwrap function
{
if (g_unwrap.m_wrapLayers > 0) {
cout << "Gift being unwrapped." << endl;
g_unwrap.m_wrapLayers = 0;
g_unwrap.m_wrap->m_pattern = nullptr;
return true;
}
else
{
cout << "Gift isn't wrapped! Can't unwrap." << endl;
return false;
}
}
void display(const Gift& theGift)
{
cout << "Gift Details:" << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
if (theGift.m_wrap == nullptr) // this part seems like a problem
{
cout << "Unwrapped" << endl;
}
else
{
int i = 0;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << ": " << theGift.m_wrap[i].m_pattern << endl;
}
}
}
void gifting(Gift& gift) //last function
{
cout << "Preparing a gift..." << endl;
gifting(gift.m_description);
gifting(gift.m_price);
gifting(gift.m_units);
wrap(gift);
}
}
</code></pre>
/***********************************************************************
// Workshop 2: Dynamic Memory & Function Overloading
// Version 2.0
// Date 2020/05/05
// Author Michael Huang
// Description
// Tests Gift module and provides a set of TODOs to complete
// which the main focuses are dynamic memory allocation
//
/////////////////////////////////////////////////////////////////
***********************************************************************/
#include <iostream>
#include "Gift.h"
#include "Gift.h" // intentional
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
<pre><code>
int main() {
Gift g1; // Unwrapped Gift
{
printHeader("T1: Checking Constants");
cout << "MAX_DESC: " << sdds::MAX_DESC << endl;
cout << "MAX_PRICE: " << sdds::MAX_PRICE << endl;
cout << "MAX_WRAP: " << sdds::MAX_WRAP << endl;
cout << endl;
}
{
printHeader("T2: Display Wrapped Gift");
gifting(g1.m_description);
gifting(g1.m_price);
gifting(g1.m_units);
cout << endl;
g1.m_wrap = nullptr;
g1.m_wrapLayers = 0;
display(g1);
cout << endl;
}
{
printHeader("T3: Wrap a gift");
if (wrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: wrapping didn't happen!" << endl;
cout << endl << endl;
}
{
printHeader("T4: Re-wrap a gift");
cout << "Attempting to rewrap the previous Gift: "
<< g1.m_description << endl;
if (wrap(g1) == false)
cout << "Test succeeded!";
else
cout << "Test failed: gift it's already wrapped, cannot wrap again!";
cout << endl << endl;
}
{
printHeader("T5: Unwrap a gift");
cout << "Attempting to unwrap the previous gift: "
<< g1.m_description << endl;
if (unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should be able to unwrap!";
cout << endl << endl;
}
{
printHeader("T6: Unwrap again");
cout << "Attempting to un-unwrap the previous gift: "
<< g1.m_description << endl;
if (!unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should not be able to unwrap again!";
cout << endl << endl;
}
Gift g2; // Unwrapped Gift
{
printHeader("T7: Prepare another gift");
g2.m_wrap = nullptr;
g2.m_wrapLayers = 0;
gifting(g2);
cout << endl;
display(g2);
cout << endl;
}
{
printHeader("T8: Unwrap the second gift");
unwrap(g2);
}
return 0;
}
Output matches perfectly but I don't know why memory leaks.. please help me. I am doubting my wrap part but I think there must be something else since deallocation seems fine.
I tried my best but I still cannot see which part is wrong.
I cannot see why my deallocation does not work I tried changing it so many times but nothing works.
On this line:
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
You allocate memory, but later you only:
delete[]m_wrap.m_wrap;
Also in your for loop you allocate memory, then get some input and store that inside the pointer, as a memory address. Should you ever dereference that, you will invoke undefined behavior, in practice that may likely will a segfault. You should consider rewriting at least that part from scratch.
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
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()
{
...
}
...
}
this is an update to show chages, details below.
here is a link to snap shot of output
https://dl.dropboxusercontent.com/u/34875891/wrongoutput.PNG
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
using namespace std;
//create HotelRoom class
class HotelRoom
{
private:
char* ptr_guest;
char room_number[3];
int room_capacity;
int occupancy_status;
double daily_rate;
public:
HotelRoom(char roomNumber[], int roomCapacity, double roomRate, char* ptr_name, int occupancyStatus);
~HotelRoom();
void Display_Number();
void Display_Guest();
int Get_Capacity();
int Get_Status();
double Get_Rate();
int Change_Status(int);
double Change_Rate(double);
};
HotelRoom::HotelRoom(char roomNumber[], int roomCapacity, double roomRate, char* ptr_name, int occupancyStatus)
{
strcpy(room_number, roomNumber);
room_capacity = roomCapacity;
daily_rate = roomRate;
ptr_guest = new char[strlen(ptr_name) + 1];
strcpy(ptr_guest, ptr_name);
occupancy_status = occupancyStatus;
}
HotelRoom::~HotelRoom()
{
cout << endl;
cout << "Destructor Executed";
cout << endl;
delete [] ptr_guest;
}
void HotelRoom::Display_Guest()
{
char* temp = ptr_guest;
while(*temp != '\0')
cout << *temp++;
}
void HotelRoom::Display_Number()
{
cout << room_number;
}
int HotelRoom::Get_Capacity()
{
return room_capacity;
}
int HotelRoom::Get_Status()
{
return occupancy_status;
}
double HotelRoom::Get_Rate()
{
return daily_rate;
}
int HotelRoom::Change_Status(int roomStatus)
{
if(roomStatus <= room_capacity )
{
occupancy_status = roomStatus;
return occupancy_status;
}
else
occupancy_status = -1;
}
double HotelRoom::Change_Rate(double newRate)
{
daily_rate = newRate;
return daily_rate;
}
int main()
{
cout << setprecision(2)
<< setiosflags(ios::fixed)
<< setiosflags(ios::showpoint);
//Declare variables to hold data
char roomNumber[3] = {'1','3','\0'};
char guestName[20];
double roomRate = 89.00;
int roomCapacity = 4;
int occupancyStatus = 0;
int status;
int checkOut;
int newCustomer;
//Ask for user input
cout << "What is the guest's name: ";
cin.getline(guestName, 20);
cout << endl;
cout << "How many guests will be staying in the room: ";
cin >> status;
HotelRoom HotelRoom1(roomNumber, roomCapacity, roomRate, guestName, status);
//Display Rooom information
cout << endl;
cout << endl;
if(HotelRoom1.Change_Status(status))
{
cout << endl;
cout << "Guest's Name: ";
HotelRoom1.Display_Guest();
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity() << endl;
cout << endl;
cout << "There are " << HotelRoom1.Get_Status() << " guests staying in the room";
}
cout << endl;
cout << endl;
cout << "Your room number is " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The rate for this room is " << HotelRoom1.Get_Rate();
cout << endl;
cout << endl;
//chech this guest out?
cout << "Check this guest out? ('1 = yes' '0' = no) ";
cin >> checkOut;
switch(checkOut)
{
case 1:
HotelRoom1.Change_Status(0);
for(int i = 0; i < 3; ++i )
{
cout << endl;
}
cout << "You have checked out of room number " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity();
cout << endl;
cout << endl;
cout << "There are currently " << HotelRoom1.Get_Status() << " occupants";
cout << endl;
cout << endl;
cout << "The rate of this room was " << HotelRoom1.Get_Rate();
break;
}
//check in new guest?
cout << endl;
cout << endl;
cout << "Check in new guest? ('1 = yes' '0' = no) ";
cin >> newCustomer;
for(int i = 0; i < 3; ++i )
{
cout << endl;
}
switch (newCustomer)
{
case 1:
HotelRoom HotelRoom2(roomNumber, roomCapacity, roomRate, guestName, status);
HotelRoom1.Change_Rate(175.00); //Change rate of room
cout << endl;
cout << "What is the guest's name: ";
cin.getline(guestName, 20);
cout << endl;
cout << "How many guests will be staying in the room: ";
cin >> status;
cout << endl;
cout << endl;
//Display new guest information
if(HotelRoom1.Change_Status(status))
{
cout << endl;
cout << endl;
cout << "The capacity of this room is " << HotelRoom1.Get_Capacity() << endl;
cout << endl;
cout << "There are " << HotelRoom1.Get_Status() << " guests staying in the room";
}
cout << endl;
cout << endl;
cout << "Your room number is " << HotelRoom1.Display_Number();
cout << endl;
cout << endl;
cout << "The rate for this room is " << HotelRoom1.Get_Rate();
cout << endl;
cout << endl;
break;
}
cout << endl;
system("PAUSE");
return 0;
}
this is an update to show chages, details below.
here is a link to snap shot of output
https://dl.dropboxusercontent.com/u/34875891/wrongoutput.PNG
char HotelRoom::Display_Guest()
{
cout << ptr_guest;
}
string HotelRoom::Display_Number()
{
cout << room_number;
}
int HotelRoom::Change_Status(int roomStatus)
{
if(roomStatus <= room_capacity )
{
occupancy_status = roomStatus;
return occupancy_status;
}
else
occupancy_status = -1;
}
These functions claim to be returning values. The first two are not, the last is not under certain conditons. Calling the first two is undefined behavior. Calling Change_Status with roomStatus > room_capacity is also undefined behavior.
There may be other problems with the code, but the elephant in the room is the undefined behavior. Any other debugging while you have undefined behavior is theoretically a waste of time.