C++ Inheritance is not working properly - c++

#include <iostream>
using namespace std;
class Item {
private:
int _code;
int _color;
int _brand;
double _height;
double _length;
double _width;
double _weight;
double _price;
int _type;
bool _doesItHaveThis;
public:
Item();
Item(int code, int color, int brand, double height, double length, double width,
double weight, double price, int type, bool doesItHaveThis);
void setCode(int code);
void setColor(int color);
void setBrand(int brand);
void setHeight(double height);
void setLength(double length);
void setWidth(double width);
void setWeight(double weight);
void setPrice(double price);
void setType(int type);
void setDoesItHaveThis(bool doesItHaveThis);
int getCode();
int getColor();
int getBrand();
double getHeight();
double getLength();
double getWidth();
double getWeight();
double getPrice();
int getType();
bool getDoesItHaveThis();
virtual ~Item();
void display();
};
//----------------------------------------------------------
Item::Item()
{
_code = 0;
_color = 0;
_brand = 0;
_height = 0;
_length = 0;
_width = 0;
_weight = 0;
_price = 0;
_type = 0;
_doesItHaveThis = 0;
}
//----------------------------------------------------------
Item::Item(int code, int color, int brand, double height, double length, double width,
double weight, double price, int type, bool doesItHaveThis)
{
_code = code;
_color = color;
_brand = brand;
_height = height;
_length = length;
_width = width;
_weight = weight;
_price = price;
_type = type;
_doesItHaveThis = doesItHaveThis;
}
//----------------------------------------------------------
void Item::setCode(int code)
{
_code = code;
}
//----------------------------------------------------------
void Item::setColor(int color)
{
_color = color;
}
//----------------------------------------------------------
void Item::setBrand(int brand)
{
_brand = brand;
}
//----------------------------------------------------------
void Item::setHeight(double height)
{
_height = height;
}
//----------------------------------------------------------
void Item::setLength(double length)
{
_length = length;
}
//----------------------------------------------------------
void Item::setWidth(double width)
{
_width = width;
}
//----------------------------------------------------------
void Item::setWeight(double weight)
{
_weight = weight;
}
//----------------------------------------------------------
void Item::setPrice(double price)
{
_price = price;
}
//----------------------------------------------------------
void Item::setType(int type)
{
_type = type;
}
//----------------------------------------------------------
void Item::setDoesItHaveThis(bool doesItHaveThis)
{
_doesItHaveThis = doesItHaveThis;
}
//----------------------------------------------------------
int Item::getCode()
{
return _code;
}
//----------------------------------------------------------
int Item::getColor()
{
return _color;
}
//----------------------------------------------------------
int Item::getBrand()
{
return _brand;
}
//----------------------------------------------------------
double Item::getHeight()
{
return _height;
}
//----------------------------------------------------------
double Item::getLength()
{
return _length;
}
//----------------------------------------------------------
double Item::getWidth()
{
return _width;
}
//----------------------------------------------------------
double Item::getWeight()
{
return _weight;
}
//----------------------------------------------------------
double Item::getPrice()
{
return _price;
}
//----------------------------------------------------------
int Item::getType()
{
return _type;
}
//----------------------------------------------------------
bool Item::getDoesItHaveThis()
{
return _doesItHaveThis;
}
//----------------------------------------------------------
Item::~Item()
{
cout << "ITEM ELIMINATED" << endl;
}
//----------------------------------------------------------
void Item::display()
{
cout << "code = " << _code << ", color = " << _color << ", brand = "
<< _brand << ", height = " << _height << ", length = " << _length
<< ", width = " << _width << ", weight = " << _weight << ", price = "
<< _price << ", type = " << _type << ", doesItHaveThis = "
<< _doesItHaveThis << endl;
}
//----------------------------------------------------------
class Pens : public Item {
private:
int _code;
int _color;
int _brand;
double _height;
double _length;
double _width;
double _weight;
double _price;
int _type;
bool _doesItHaveThis;
int _packetSize;
public:
Pens();
Pens(int code, int color, int brand, double height, double length, double width,
double weight, double price, int type, bool doesItHaveThis, int packetSize);
void setPacketSize(int packetSize);
int getPacketSize();
virtual ~Pens();
void display();
};
//----------------------------------------------------------
Pens::Pens()
{
_code = 0;
_color = 0;
_brand = 0;
_height = 0;
_length = 0;
_width = 0;
_weight = 0;
_price = 0;
_type = 0;
_doesItHaveThis = 0;
_packetSize = 0;
}
//----------------------------------------------------------
Pens::Pens(int code, int color, int brand, double height, double length, double width,
double weight, double price, int type, bool doesItHaveThis, int packetSize)
{
_code = code;
_color = color;
_brand = brand;
_height = height;
_length = length;
_width = width;
_weight = weight;
_price = price;
_type = type;
_doesItHaveThis = doesItHaveThis;
_packetSize = packetSize;
}
//----------------------------------------------------------
void Pens::setPacketSize(int packetSize)
{
_packetSize = packetSize;
}
//----------------------------------------------------------
int Pens::getPacketSize()
{
return _packetSize;
}
//----------------------------------------------------------
Pens::~Pens()
{
cout << "PEN ELIMINATED" << endl;
}
//----------------------------------------------------------
void Pens::display()
{
cout << "code = " << _code << ", color = " << _color << ", brand = "
<< _brand << ", height = " << _height << ", length = " << _length
<< ", width = " << _width << ", weight = " << _weight << ", price = "
<< _price << ", type = " << _type << ", doesItHaveThis = "
<< _doesItHaveThis << ", packetSize = " << _packetSize << endl;
}
//----------------------------------------------------------
void main()
{
Pens I1(1, 2, 3, 4.1, 2.0, 3.4, 3.3, 3.2, 5, 1, 0);
I1.setBrand(999);
I1.setDoesItHaveThis(0);
I1.setHeight(34.62);
I1.display();
}
So this is my code, and I'm wondering why the Pens class is not properly inheriting the public methods of the Item class. When I run this code, the setBrand(999), setDoesItHaveThis, and setHeight don't work from what I can tell from the output. Can anybody tell what I did wrong?

The way to use polymorphism is to inherit the members of the base class. If you repeat them instead, then this will declare another member of the same name.
struct base
{
int member1 = 0; // the =0 means that these members
int member2 = 0; // will be default initialised to 0
base() = default;
explicit base(int i, int j=0)
: member1(i), member2(j) {}
};
struct derived
: base
{
int member1 = 1; // not to be confused with base::member1
int member3 = 4;
derived() = default;
explicit derived(int i, int j=0, int k=1, int m=4)
: base(i,j), member1(k), member3(m) {}
int foo() const
{ return member1 * base::member1; }
};
Here, derived has two members member1: one inherited from base and another not inherited. These two can be easily confused by a programmer (but not by the compiler). So such constructs should be avoided (and good compilers will warn you).

In the derived class call the base class constructor with all the arguments you need. And like pointed out in the comments do not redeclare all the base class variables as new members of the derived class. To set/get the base class member variables use the Setters and Getters that you have made public in your base class (these get inherited by the derived class). (Although I would make the setters protected if I were you). Also look in to initializer lists in constructors instead of initializing each member in the body - Read this

Related

Derived classes' attributes are empty

I am new to C++ and I am currently playing with inheritance. I am creating a base Polygon class that is inherited by Rectangle and Triangle classes respectively. From there I want to print out the area as defined in calcArea. However, the output of my derived class instances seem to be null.
From what I understand the Polygon:(name, width, height) can help to initialize variables that already exist in the base class. Thanks for all the help!
Here's my code:
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
virtual ~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype = POLY_RECT;
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}
And here's my output:
Name is
Name is
RectA's area is 0.000000
TriangB's area is 0.000000
Destroying triangle
Destroying polygon
Destroying rectangle
Destroying polygon
The main problem is that you have variables in the sub classes shadowing the names in the base class - so you assign values to the variables in the base class, but you later print the values of the default initialized variables in the sub classes.
You actually mostly need to remove code.
I would rethink the name of the base class though. Polygon is not a good name for a class with only width and height. I'll leave that up to you.
I've replaced all endl with \n. They do the same thing, but endl flushes the output, which is usually not needed - but it is usually also expensive.
Example:
#include <iostream>
#include <string>
enum Polytype { POLY_PLAIN, POLY_RECT, POLY_TRIANG };
class Polygon {
public:
Polygon(std::string name, double width, double height)
: Polygon(name, width, height, POLY_PLAIN) {}
virtual ~Polygon() { std::cout << "Destroying polygon\n"; }
// make member functions that does not change the object `const`:
virtual Polytype getPolytype() const { return _polytype; }
virtual void setPolytype(Polytype polytype) { _polytype = polytype; }
virtual const std::string& getName() const { return _name; }
// in your case, the implementation could actually be in the base class - but
// I've made it into a pure virtual here.
virtual double calcArea() const = 0; // no instances can be made of Polygon
protected:
// only derived classes can access this constructor:
Polygon(std::string name, double width, double height, Polytype ptype)
: _name(name), _width(width), _height(height), _polytype(ptype) {}
std::string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle : public Polygon {
public:
Rectangle(std::string name, double width, double height)
//use the protected base class ctor:
: Polygon(name, width, height, POLY_RECT) {};
~Rectangle() { std::cout << "Destroying rectangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return _width * _height; }
};
class Triangle : public Polygon {
public:
Triangle(std::string name, double width, double height)
: Polygon(name, width, height, POLY_TRIANG) {};
~Triangle() { std::cout << "Destroying triangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return 0.5 * _width * _height; }
};
int main() {
// Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
std::cout << "Name is " << rect.getName() << '\n';
std::cout << "Name is " << triang.getName() << '\n';
std::cout << "RectA's area is " << rect.calcArea() << '\n';
std::cout << "TriangB's area is " << triang.calcArea() << '\n';
}
I realized that I did not have to redeclare the private variables in my subclasses. That is probably the reason why it returned null.
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
protected:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}

Deep copy unsuccessful

might be a stupid question and if it is, let me know, I will delete it as soon as possible. The thing is I have to make a deep copy in class "Kambarys" (ignore mixed languages, I know I shouldn't do that). Program terminates after trying to call function second time. Probably the problem is my syntax in constructor copy, but I can't find the correct one anywhere. One of the requirements is to create langas, durys and kambarys in dynamic memory using "new" and delete windows vector and door in Kambarys destructor. Appreciate the help!
Requirements:
In the main method, use the new operator to create room k1, add windows and doors to it. Write a constructor Room (const Room & k) that would create a correct copy. In the method main, write another room k2. Calculate the length of the baseboards / wall area.
Perform the following steps: k2 = * k1; delete k1;
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
class Langas{
private:
float height;
float widht;
static int countL;
public:
Langas(float h, float w){
this->height=h;
this->widht=w;
countL++;
}
~Langas(){
--countL;
}
float getHeight(){
return height;
}
float getWidht(){
return widht;
}
static int getWindowCount(){
return countL;
}
};
class Durys{
private:
float heightD;
float widhtD;
static int countD;
public:
Durys(float hD, float wD){
this->heightD=hD;
this->widhtD=wD;
countD++;
}
~Durys(){
--countD;
}
float getHeightD(){
return heightD;
}
float getWidhtD(){
return widhtD;
}
static int getDoorCount(){
return countD;
}
};
class Kambarys{
private:
float heightK;
float widhtK;
float lenghtK;
public:
vector<Langas*> windows;
Durys* door;
Kambarys(float hK, float wK, float lK){
this->heightK=hK;
this->widhtK=wK;
this->lenghtK=lK;
}
Kambarys(const Kambarys &k){
this->door=k.door;
this->windows=k.windows;
heightK=k.heightK;
widhtK=k.widhtK;
lenghtK=k.lenghtK;
}
~Kambarys(){
door=NULL;
for(int i=0; i<windows.size(); i++){
delete windows[i];
}
windows.clear();
delete door;
}
float getHeightK(){
return heightK;
}
float getWidhtK(){
return widhtK;
}
float getLenghtK(){
return lenghtK;
}
void addWindow(Langas* w){
windows.push_back(w);
}
void addDoor(Durys *d){
door=d;
}
};
float countWallPlot(Kambarys* k){
float cWPlot=(2*k->getLenghtK()*k->getHeightK())+(2*k->getWidhtK()*k->getHeightK());
for(int i=0; i<k->windows.size(); i++){
cWPlot-=((k->windows[i]->getHeight()))*(k->windows[i]->getWidht());
}
cWPlot-=((k->door->getHeightD()))*(k->door->getWidhtD());
return cWPlot;
}
float countLenght(Kambarys* k){
float floorL=(k->getLenghtK()*k->getWidhtK()*2);
floorL-=(k->door->getWidhtD());
return floorL;
}
int Langas::countL=0;
int Durys::countD=0;
int main(){
Langas *langas1=new Langas(3.4, 1.2);
Durys *durys=new Durys(3.1, 1.5);
Langas *langas2=new Langas(6.4, 1.5);
Kambarys *k=new Kambarys(30.4, 40.1, 50.1);
Kambarys *k2=k;
k->addWindow(langas1);
k->addWindow(langas2);
k->addDoor(durys);
cout<<countWallPlot(k)<<" "<<countLenght(k)<<endl;
cout<<"Window count "<<Langas::getWindowCount()<<", door count "<<Durys::getDoorCount()<<endl;
k2=k;
delete k;
cout<<countWallPlot(k2)<<" "<<countLenght(k2)<<endl;
cout<<"Window count "<<Langas::getWindowCount()<<", door count "<<Durys::getDoorCount()<<endl;
}
You have to allocate memory for k2 and copy the object, not the pointer.
You have to allocate memory in the copy constructor and copy assignment operator.
door=NULL; before delete door; would skip the delete and cause a memory leak.
windows.clear(); is not necessary in the destructor. Keep your code simple.
EDIT: After you added "Perform the following steps: k2 = * k1; delete k1;" I made k2 an object, not a pointer.
#include <iostream>
#include <vector>
class Langas {
private:
float height;
float width;
static int count;
public:
Langas(float h, float w): height(h), width(w) {
++count;
}
~Langas() { --count; }
float getHeight() const { return height; }
float getWidht() const { return width; }
static int getWindowCount() { return count; }
};
class Durys {
private:
float height;
float width;
static int count;
public:
Durys(float h, float w): height(h), width(w) {
++count;
}
~Durys() { --count; }
float getHeight() const { return height; }
float getWidth() const { return width; }
static int getDoorCount() { return count; }
};
class Kambarys {
private:
float height;
float width;
float length;
public:
std::vector<Langas *> windows;
Durys *door = nullptr;
Kambarys(float hK, float wK, float lK): height(hK), width(wK), length(lK) {}
Kambarys(const Kambarys &k): height(k.height), width(k.width), length(k.length), windows(), door(k.door ? new Durys(k.door->getHeight(), k.door->getWidth()) : nullptr) {
for (const auto window : k.windows) {
windows.emplace_back(new Langas(window->getHeight(), window->getWidht()));
}
}
Kambarys &operator=(const Kambarys &k) {
door = k.door ? new Durys(k.door->getHeight(), k.door->getWidth()) : nullptr;
for (const auto window : k.windows) {
windows.emplace_back(new Langas(window->getHeight(), window->getWidht()));
}
height = k.height;
width = k.width;
length = k.length;
return *this;
}
~Kambarys() {
for (auto window : windows) {
delete window;
}
delete door;
}
float getHeight() const { return height; }
float getWidth() const { return width; }
float getLength() const { return length; }
void addWindow(Langas *w) { windows.emplace_back(w); }
void addDoor(Durys *d) { door = d; }
};
float countWallPlot(const Kambarys &k) {
float cWPlot = 2 * k.getLength() * k.getHeight() + 2 * k.getWidth() * k.getHeight();
for (const auto window : k.windows) {
cWPlot -= window->getHeight() * window->getWidht();
}
cWPlot -= k.door->getHeight() * k.door->getWidth();
return cWPlot;
}
float countLength(const Kambarys &k) {
float floor = k.getLength() * k.getWidth() * 2;
floor -= k.door->getWidth();
return floor;
}
int Langas::count = 0;
int Durys::count = 0;
int main() {
Langas *langas1 = new Langas(3.4, 1.2);
Durys *durys = new Durys(3.1, 1.5);
Langas *langas2 = new Langas(6.4, 1.5);
Kambarys *k = new Kambarys(30.4, 40.1, 50.1);
Kambarys k2(*k);
k->addWindow(langas1);
k->addWindow(langas2);
k->addDoor(durys);
std::cout << countWallPlot(*k) << " " << countLength(*k) << std::endl;
k2 = *k;
std::cout << "Window count " << Langas::getWindowCount() << ", door count " << Durys::getDoorCount() << std::endl;
delete k;
std::cout << countWallPlot(k2) << " " << countLength(k2) << std::endl;
std::cout << "Window count " << Langas::getWindowCount() << ", door count " << Durys::getDoorCount() << std::endl;
}

How do I return an average of a number of vector objects? C++

Hi I'm quite new to c++ and I have a project but to do but a question in the project requires me to add a function, getAverageCostPerDay(), which takes a vector of Reservations object and returns the average cost of a car reservation. How do I got about doing this? Thanks
Reservation.h
#pragma once
#include <string>
class Reservation
{
private:
int id;
std::string name;
int stDate;
int stMonth;
int stYear;
int duration;
float cost;
std::string licensePlate;
static int reservationCount;
public:
//Constructor
Reservation();
Reservation(int id, std::string name, int stDate, int stMonth, int
stYear, int duration, float cost, std::string licensePlate);
//Destructor
~Reservation();
//Getters
int getId();
std::string getName();
int getStDate();
int getStMonth();
int getStYear();
int getDuration();
float getCost();
std::string getLicensePlate();
//Setters
void setId(int id);
void setName(std::string name);
void setStDate(int stDate);
void setStMonth(int stMonth);
void setStYear(int stYear);
void setDuration(int duration);
void setCost(float cost);
void setLicensePlate(std::string licensePlate);
static int getReservationCount()
{
return reservationCount;
}
};
Reservation.cpp
#include "pch.h"
#include "Reservation.h"
int Reservation::reservationCount = 0;
//Constructor
Reservation::Reservation()
{
this->id = 0;
this->name = "";
this->stDate = 0;
this->stMonth = 0;
this->stYear = 0;
this->duration = 0;
this->cost = 0;
this->licensePlate = "";
reservationCount++;
}
Reservation::Reservation(int id, std::string name, int stDate, int stMonth,
int stYear, int duration, float cost, std::string licensePlate)
{
this->id = id;
this->name = name;
this->stDate = stDate;
this->stMonth = stMonth;
this->stYear = stYear;
this->duration = duration;
this->cost = cost;
this->licensePlate = licensePlate;
reservationCount++;
}
//Destructor
Reservation::~Reservation()
{
reservationCount--;
std::cout << "Destroying (" << this->name << ")" << std::endl;
}
//Getters
int Reservation::getId()
{
return this->id;
}
std::string Reservation::getName()
{
return this->name;
}
int Reservation::getStDate()
{
return this->stDate;
}
int Reservation::getStMonth()
{
return this->stMonth;
}
int Reservation::getStYear()
{
return this->stYear;
}
int Reservation::getDuration()
{
return this->duration;
}
float Reservation::getCost()
{
return this->cost;
}
std::string Reservation::getLicensePlate()
{
return this->licensePlate;
}
//Setters
void Reservation::setId(int id)
{
this->id = id;
}
void Reservation::setName(std::string name)
{
this->name = name;
}
void Reservation::setStDate(int stDate)
{
this->stDate = stDate;
}
void Reservation::setStMonth(int stMonth)
{
this->stMonth = stMonth;
}
void Reservation::setStYear(int stYear)
{
this->stYear = stYear;
}
void Reservation::setDuration(int duration)
{
this->duration = duration;
}
void Reservation::setCost(float cost)
{
this->cost = cost;
}
void Reservation::setLicensePlate(std::string licensePlate)
{
this->licensePlate = licensePlate;
}
Main.cpp
#include "pch.h"
#include "Reservation.h"
//Regular Expressions
std::string idRegexStr = "[0-9]{3,4}";
std::string nameRegexStr = "[A-Za-z]{1}[a-z]{1,30} [A-Za-z]{1}[a-z]{1,30}";
std::string stDateRegexStr = "[0-3]{1}[0-9]{1}";
std::string stMonthRegexStr = "[0-1]{1}[0-9]{1}";
std::string stYearRegexStr = "[1-2]{1}[0-9]{1}[0-9]{1}[0-9]{1}";
std::string durationRegexStr = "[1-9]{1}[0-9]{1}";
std::string costRegexStr = "[0-9]{2}.[0-9]{2}";
std::string licencePlateRegexStr = "[0-9]{2,3}\\s*[A-Z]{2,3}\\s*[0-9]+";
//Validates data against a user-defined string
bool validate(std::string regexStr, std::string data)
{
return std::regex_match(data, std::regex(regexStr));
}
std::vector<Reservation>populateVector(Reservation defaultVector, int size)
{
std::vector<Reservation> outVector;
for (int i = 0; i < size; i++)
{
outVector.push_back(defaultVector);
}
return outVector;
}
double getAverageCostPerDay(const std::vector<Reservation> outVector)
{
double average = 0;
for (std::size_t i = 0; i < outVector.size(); i++)
{
average = std::vector<Reservation>outVector.at(float cost);
}
return true;
}
int main()
{
/*
//these were example values to see if regex works
bool idIsValid = validate(idRegexStr, "101");
bool nameIsValid = validate(nameRegexStr, "John Smith");
bool stDateIsValid = validate(stDateRegexStr, "24");
bool stMonthIsValid = validate(stMonthRegexStr, "10");
bool stYearIsValid = validate(stYearRegexStr, "2018");
bool durationIsValid = validate(durationRegexStr, "10");
bool costIsValid = validate(costRegexStr, "22.50");
bool licenseIsValid = validate(licencePlateRegexStr, "181 LH 555");
std::cout << "Invalid = 0 / Valid = 1\n";
std::cout << "\n";
std::cout << "Valid ID: " << idIsValid << std::endl;
std::cout << "Valid Name: " << nameIsValid << std::endl;
std::cout << "Valid Start Date: " << stDateIsValid << std::endl;
std::cout << "Valid Start Month: " << stMonthIsValid << std::endl;
std::cout << "Valid Start Year: " << stYearIsValid << std::endl;
std::cout << "Valid Duration: " << durationIsValid << std::endl;
std::cout << "Valid Cost: " << costIsValid << std::endl;
std::cout << "Valid License: " << licenseIsValid << std::endl;
*/
Reservation r1(101, "John Smith", 24, 10, 2018, 4, 22.50, "181 LH
5555");
Reservation r2(102, "Jane Caroll", 31, 01, 2017, 6, 34.25, "161 DUB
55454");
Reservation r3(103, "Sean Morrissey", 16, 06, 2014, 2, 67.50, "162 WEX
83675");
Reservation r4(104, "Billy Joe", 04, 03, 2016, 8, 51.20, "152 DUB
10347");
std::cout << "Reservation Count: " << Reservation::getReservationCount()
<<
std::endl;
}
There are a couple of ways to do this.
You could wrap your vector of reservations inside of a class and keep track of how many there are, what the total cost is, and calculate the average.
However, if you have to return this information through the Reservation class, then you'll have to use a static variable for sum of costs and number of reservation objects. Static attributes are available in all objects of that class and will have the same value between all objects. So, every time you create a Reservation object, increment the count and sum of costs. Then when you need the average, you can calculate it from any of the objects or through the class (if you make a static function to do this).

How to cout 'this' with overloaded output?

In the following example, how to refer to the current object instance to take opportunity to use the output overload?
class Shape {
private:
double _length, _width;
double straight(double value) {
if (value<0) { return -value; }
if (value==0) { return 1; }
return value;
}
public:
Shape() { setDims(1,1); }
Shape(double length, double width) {
setDims(length, width); }
void setDims(double length, double width) {
_length=straight(length); _width=straight(width); }
friend ostream &operator<<(ostream &output, Shape &S) {
output << S._length << "," << S._width; return output; }
void display() { cout << [THIS] << endl; }
};
int main(int argc, const char * argv[]) {
Shape s1; s1.display();
return 0;
}
Just like this:
void display() { cout << *this << endl; }
this is a pointer. Your operator<< wants an actual Shape object, not a pointer.
So you'll have to dereference the pointer first: *this.
Alternatively just use operator<<
#include <iostream>
using namespace std;
class Shape {
private:
double _length, _width;
double straight(double value) {
if (value<0) { return -value; }
if (value == 0) { return 1; }
return value;
}
public:
Shape() { setDims(1, 1); }
Shape(double length, double width) {
setDims(length, width);
}
void setDims(double length, double width) {
_length = straight(length); _width = straight(width);
}
friend ostream &operator<<(ostream &output, Shape &S) {
output << S._length << "," << S._width; return output;
}
int main(int argc, const char * argv[]) {
Shape s1;
std::cout << s1 << std::endl;
}

Inheritance with segmentation fault

I'm working on inheritance right now. I have a base class called Shape, and few others as sub class. There is no compilation error. But after when i enter all the coordinates, segmentation error pops out. Inside the driver class, option when when i tried using this d[count].toString();
Shape.h
class Shape
{
protected:
string name;
bool containsWarpSpace;
public:
Shape();
Shape(string, bool);
string toString();
virtual double computeArea();
void setName (string);
// some other codes here
};
Square.h
class Square : public Shape
{
protected:
int *x;
int *y;
int area;
int vertices;
public:
double computeArea();
void setSquare(string, string, int*, int*);
string toString();
};
Square.cpp
void Square::setSquare(string name, string type, int* a, int* b)
{
setName(name);
setContainsWarpSpace (type);
vertices = 4;
x = new int[vertices];
y = new int[vertices];
for (int i = 0; i < vertices; i++)
{
x[i] = a[i];
y[i] = b[i];
}
}
string Square::toString()
{
ostringstream convert;
string s;
string type;
for (int i = 0; i < vertices; i++)
{
convert << "point " << i + 1
<< " ( "
<< x[i] << " , " << y[i]
<< " ) "<< endl;
}
s = convert.str();
return s;
}
Driver class with int main()
class Driver
{
public:
Driver();
Shape *d[];
Square *s;
int count;
int noSquare;
int noRectangle;
int noCross;
void printDetails();
void printPlan();
void option1();
void option2();
void option3();
void option4();
string convertString(string);
};
Driver.cpp. This is the default constructor,
Driver :: Driver()
{
Shape d [MAX];
s = new Square [MAX];
count = 0;
int noSquare = 0;
int noRectangle = 0;
int noCross = 0;
}
Driver::option1()
{
if (shape.compare("square") == 0)
{
tempx = new int[4];
tempy = new int[4];
for (int i = 0; i < 4; i++)
{
int j = i + 1;
cout << "Please enter x-ordinate of pt " << j << ": ";
cin >>tempx[i];
cout << "Please enter y-ordinate of pt " << j << ": ";
cin >>tempy[i];
}
s[noSquare].setSquare(shape,type, tempx,tempy);
d[count] = &s[noSquare];
d[count].toString();
}
}
int main ()
{
option1();
}
Change the way you declared your shape in Driver class. In the header, declare it as :
Shape* d;
and in your CPP initialize it:
d = new Shape[MAX];
Also, since you are doing inheritance and arrays and pointers, you should manage your own destructors. Because if the chil object gets destroyed, it will take parent destructor. Therefore, your destructors should be:
virtual ~Shape();
And square:
virtual ~Square();
In them, delete the pointers:
delete x; // in case of square
delete y;
And when you have arrays:
delete [] d; // in case of driver class
Otherwise it will not free memory properly. That would probably fix your problems.