Array of derived class stored in parent class - c++

I don't think I quite understand how to store an array of a derived class in its parent class.
I keep getting errors
Error C3646 'list': unknown override specifier
Error C2065 'list': undeclared identifier
Here is the code I have
#include <iostream>
#include <string>
using namespace std;
class GameScores
{
public:
GameEntry list[9];
void inputList(GameEntry x);
void sortList();
void removeList(int r);
void printList();
GameScores();
};
class GameEntry :public GameScores
{
public:
GameEntry(const string& n = "", int s = 0, const string d = "1/1/99");
string getName() const;
int getScore() const;
string getDate() const;
string setName(string n);
int setScore(int s);
string setDate(string d);
private:
string name;
int score;
string date;
};
GameScores::GameScores()
{
GameEntry list[9];
}
void GameScores::inputList(GameEntry x)
{
for (int i = 0; i < 10; i++)
if (x.getScore() >= list[i].getScore())
{
list[i + 1] = list[i];
list[i] = x;
}
}
void GameScores::sortList()
{
GameEntry swap;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10 - 1; j++)
{
if (list[j].getScore() > list[j].getScore() + 1)
{
swap = list[j];
list[j] = list[j + 1];
list[j + 1] = swap;
}
}
}
}
void GameScores::removeList(int r)
{
for (int i = r; i < 10; i++)
list[i - 1] = list[i];
list[9].setScore(0);
list[9].setName(" ");
list[9].setDate(" ");
}
void GameScores::printList()
{
cout << "Top Scores" << endl;
for (int i = 0; i < 10; i++)
cout << list[i].getScore() << " " << list[i].getName() << " " << list[i].getDate() << endl;
}
GameEntry::GameEntry(const string& n, int s, const string d) // constructor
: name(n), score(s), date(d) { }
// accessors
string GameEntry::getName() const { return name; }
int GameEntry::getScore() const { return score; }
string GameEntry::getDate() const { return date; }
string GameEntry::setName(string n)
{
name = n;
}
int GameEntry::setScore(int s)
{
score = s;
}
;
string GameEntry::setDate(string d)
{
date = d;
}
int main()
{
GameEntry p1("John", 90, "9/9/98"), p2("Jane", 95, 8/21/98), p3("Bob", 60, "7/11/99"), p4("Jo", 92, "6/4/97");
GameScores topScores;
topScores.inputList(p1);
topScores.inputList(p2);
topScores.inputList(p3);
topScores.inputList(p4);
topScores.printList();
return 0;
}

This design is very questionable. What purpose is being served by making the second class inherit the first? It looks like you'd end up with each member of the array containing an additional array with all its siblings. Don't you want only one array? You need to rethink this from an earlier point.
If you really have a reason for a parent class to contain an array of the child class, maybe you should define an interface (abstract base class) that both classes implement.

To use GameEntry as a type in your GameScores class , you must forward-declare the class like so :
class GameEntry;
class GameScores
{
public:
GameEntry list[9];
void inputList(GameEntry x);
void sortList();
void removeList(int r);
void printList();
GameScores();
};

Related

Access violation executing in classes with inheritance/ c++

I have a base class Participant and I need to sort object in array of participant by quantity of their prizes or diplomas. The virtual function get_data return this number. But whileI try to sort, i've got error Access violation executing in row with comparing 2 numbers.
if (p[j].Get_Data() < p[i].Get_Data()) {
This is my full code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Participant {
protected:
string name;
string surname;
vector <string> type;
int age;
public:
Participant() : name(""), surname(""), type(), age(0)
{}
Participant(string name, string surname, vector <string> type, int age) {
this->name = name;
this->surname = surname;
this->type = type;
this->age = age;
};
Participant(const Participant& other) : name(other.name), surname(other.surname), type(other.type), age(other.age)
{
}
Participant& operator=(const Participant& other)
{
name = other.name;
surname = other.surname;
type = other.type;
age = other.age;
return *this;
}
virtual int Get_Data() {
return 0;
}
friend void Sort(Participant* p);
};
class Diploma : public Participant {
protected:
vector<int> places;
vector <string> type_d;
public:
Diploma() : places(), type_d{}
{}
Diploma(string name, string surname, vector <string> type, int age, vector<int> places, vector <string> type_d);
int Get_Data() override {
cout << "diplom prize" << endl;
cout << type_d.size() << endl;
return type_d.size();
}
};
class Prize : public Participant {
protected:
vector <int> places;
vector<string> prize;
public:
Prize(string name, string surname, vector <string> type, int age, vector<int> places, vector<string> prize);
int Get_Data() override{
cout << "Cont prize" << endl;
cout << prize.size() << endl;
return prize.size();
}
};
Prize::Prize(string name, string surname, vector <string> type, int age, vector<int> places, vector<string> prize) {
this->name = name;
this->surname = surname;
this->type = type;
this->age = age;
this->places = places;
this->prize = prize;
}
Diploma::Diploma(string name, string surname, vector <string> type, int age, vector<int> places, vector <string> type_d){
this->name = name;
this->surname = surname;
this->type = type;
this->age = age;
this->places = places;
this->type_d = type_d;
}
void Sort(Participant* p) {
Participant temp;
for (int i = 0; i < 3; i++) {
for (int j = i + 1; j < 3; j++)
{
if (p[j].Get_Data() < p[i].Get_Data()) {
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
int main() {
Participant* pa[3];
pa[0] = new Diploma("Alex", "Smith", { "Geo","Math" }, 17, { 1,6 }, { "first"});
pa[1] = new Prize("Helen", "Blink", { "IT","Math" }, 18, { 2,2 }, {"Golden medal", "medal"});
pa[2] = new Prize("Brandon", "Brown", { "IT","Math" }, 18, { 2,2 }, { "Golden medal", "medal","gold"});
Sort(*pa);
for (int i = 0; i < 3; i++) {
pa[i]->Get_Data();
cout << endl;
}
}
The issue here is that when you are passing *pa, only the first element is accessible. If you run it in debug mode you will be able to see that inside sort function, p[1] is not a valid object. Basically, only p[0] is passed to the function. You should pass the reference to the array i.e. **pa to the sort function
void Sort(Participant **p)
{
Participant *temp;
for (int i = 0; i < 3; i++)
{
for (int j = i + 1; j < 3; j++)
{
if (p[j]->Get_Data() < p[i]->Get_Data())
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
int main()
{
Participant *pa[3];
pa[0] = new Diploma("Alex", "Smith", {"Geo", "Math"}, 17, {1, 6}, {"first"});
pa[1] = new Prize("Helen", "Blink", {"IT", "Math"}, 18, {2, 2}, {"Golden medal", "medal"});
pa[2] = new Prize("Brandon", "Brown", {"IT", "Math"}, 18, {2, 2}, {"Golden medal", "medal", "gold"});
Sort(pa);
for (int i = 0; i < 3; i++)
{
pa[i]->Get_Data();
cout << endl;
}
}

Sorting class array in ascending order

Quite new to programming and in need of some help, I'm looking to sort an class array in ascending order based on age, but I can only get the code to work in descending order. I may be overlooking something small since I've worked on this far too long so I'd appreciate any help!
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
string name;
int age;
Person(string name = "empty", int age = 0)
{
setName(name);
setAge(age);
}
void setName(string x) {
name = x;
}
string getName() {
return name;
}
void setAge(int y) {
age = y;
}
int getAge() {
return age;
}
void displayinfo()
{
cout << "Name: " << name; cout << " Age: " << age << endl;
}
};
void swap(Person &p, Person &q)
{
Person temp;
temp.name = p.name;
temp.age = p.age;
p.name = q.name;
p.age = q.age;
q.name = temp.name;
q.age = temp.age;
}
int main()
{
int userValue;
Person po("Jessica", 24);
Person po2("Robert", 49);
Person po3("Maria", 47);
Person po4("John", 19);
Person family[4] = {po,po2,po3,po4};
int sort(family[4].getAge());
{
for(int i = 0; i < 3; i++)
if (family[i].getAge() < family[i+1].getAge())
{
swap(family[i], family[i+1]);
}
}
for(int i = 0; i < 4; i++)
family[i].displayinfo();
}
int sort(family[4].getAge()); is not a function declaration (and you can't implement a function inside of another function). It is actually a variable declaration. It is declaring a variable int sort that is initialized with the value from family[4].getAge() (which is undefined behavior since index 4 is out of bounds of your family[] array).
So, you are declaring an unused sort variable, and then you enter your for(int i = 0; i < 3; i++) loop, which DOES NOT perform a full sort of the array. For what you are attempting, use the standard std::sort() algorithm instead, eg:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Person
{
public:
string name;
int age;
Person(string name = "empty", int age = 0)
{
setName(name);
setAge(age);
}
void setName(string x) {
name = x;
}
string getName() const {
return name;
}
void setAge(int y) {
age = y;
}
int getAge() const {
return age;
}
void displayinfo() const
{
cout << "Name: " << name; cout << " Age: " << age << endl;
}
};
int main()
{
Person po1("Jessica", 24);
Person po2("Robert", 49);
Person po3("Maria", 47);
Person po4("John", 19);
Person family[4] = {po1, po2, po3, po4};
std::sort(family, family + 4,
[](const Person &p1, const Person &p2) {
return p1.getAge() < p2.getAge();
}
);
for(int i = 0; i < 4; i++) {
family[i].displayinfo();
}
return 0;
}
Live Demo
Note that your family[] array holds copies of the Person objects that you initialize it with. To avoid the overhead of those copies, you can sort pointers instead, eg:
int main()
{
Person po1("Jessica", 24);
Person po2("Robert", 49);
Person po3("Maria", 47);
Person po4("John", 19);
Person* family[4] = {&po1, &po2, &po3, &po4};
std::sort(family, family + 4,
[](const Person *p1, const Person *p2) {
return p1->getAge() < p2->getAge();
}
);
for(int i = 0; i < 4; i++) {
family[i]->displayinfo();
}
return 0;
}
Live Demo
Or, you can get rid of the individual p0... objects altogether and initialize the array directly instead, eg:
int main()
{
Person family[4]{
{"Jessica", 24},
{"Robert", 49},
{"Maria", 47},
{"John", 19}
};
std::sort(family, family + 4,
[](const Person &p1, const Person &p2) {
return p1.getAge() < p2.getAge();
}
);
for(int i = 0; i < 4; i++) {
family[i].displayinfo();
}
return 0;
}
Live Demo

Terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc. Improper dynamic allocation?

I am attempting to create a class of MovieList that contains a dynamically allocated double [] of weeklyRevenue. I keep getting this error, I know it is associated with memory allocation, but not sure about the specifics. How can I fix this?
class Movie
{
public:
Movie();
void setMovieData(char [],char [],char, int,int,int,int,double[]);
~Movie();
string getTitle() const;
char getGenre() const;
void display() const;
double getBoxOffice();
private:
char title[75];
char director[50];
char genre;
Date releaseDate;
double* weeklyRevenue;
double* weeklyTake;
int numWeeks;
};
class MovieList
{
public:
MovieList(); //constuctor
~MovieList(); //deconstructor
int getCapacity();
int getCurrentSize();
void addMovie(char[], char[], char, int ,int, int,int, double[]);
void insertMovie(Movie, int);
void deleteMovie(char []);
void displayList() const;
void displayByGenre(char) const;
int search(char []) const;
Movie* movieListObj;
private:
int capacity, currentSize;
}
movieList.cpp:
void Movie::setMovieData(char t[], char dir[], char g, int month, int day, int year,int numWks, double wklyTake[])
{
for(int i =0; i < 75; i++)
title[i] = t[i];
for (int i = 0; i < 50; i++)
director[i] = dir[i];
genre = g;
releaseDate.setDate(month,day,year);
numWeeks = numWks;
weeklyRevenue = new double[numWeeks];
wklyTake = new double[numWeeks];
for (int i = 0; i < numWeeks; i++)
weeklyRevenue[i] = wklyTake[i];
}
Movie::~Movie()
{
delete [] weeklyTake;
weeklyTake = NULL;
delete [] weeklyRevenue;
weeklyRevenue = NULL;
}
void Movie::display() const
{
cout<<"Title: ";
for(int i =0; i < 75; i++)
cout<< title[i];
cout << "\nDirector: ";
for (int i = 0; i < 50; i++)
cout << director[i];
cout << "\nGenre:" << genre<<endl;
cout << "Release Date: ";
releaseDate.print();
cout<<"Weeks since Release: " << numWeeks<<endl;
cout <<"Box office: " ;
double BoxOffice = 0;
for(int i =0; i <numWeeks; i++)
BoxOffice += weeklyRevenue[i];
cout << BoxOffice;
}
MovieList::MovieList()
{
capacity = 5;
currentSize = 0;
movieListObj = new Movie[currentSize];
}
MovieList::~MovieList()
{
delete [] movieListObj;
movieListObj = NULL;
}
void MovieList::addMovie(char t[], char dir[], char g, int month, int day, int year, int numWeeks, double* weeklyRevenue)
{
if( currentSize >= capacity)
{
capacity += 5;
}
movieListObj[currentSize].setMovieData(t, dir, g, month, day, year, numWeeks, weeklyRevenue);
currentSize++;
}
void MovieList::insertMovie(Movie movieList, int position)
{
if(position < 0 || position > capacity)
cout << "insert failed";
else
{
movieListObj[position] = movieList;
cout << "Insert successful";
}
}
void MovieList::deleteMovie(char titleDel[])
{
for( int i= 0; i < currentSize; i++)
{
while( titleDel == movieListObj[i].getTitle())
cout<< "Delete" ;
}
}
I am attempting to add a movie, but once I enter all data in the addMovie function I get the error "terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abort"

"No instance of constructor "PlayerData::PlayerData" matches the argument list." error Visual Studio is giving me when I try to run the program

Header File
#pragma once
#ifndef PLAYERDATA_H
#define PLAYERDATA_H
#include <string>
using namespace std;
class PlayerData
{
private:
Private member variables
static const int SIZE = 10;
string name; //Player Name
int jnum; //Jersey Number
string team; //Player Team
string position; //Player position
int points[SIZE]; // Array of points for last 10 games
int rebounds[SIZE]; // Array of rebounds for last 10 games
int assist[SIZE]; // Array of assist for last 10 games
double ap = 0.0; // Average number of points
double ar = 0.0; // Average number of rebounds
double aa = 0.0; // Average number of assits
public:
Constructor to initialize data if no data is passed
// Constructor #1
PlayerData()
{
jnum = 0;
name = "";
team = "";
position = "";
for (int i = 0; i < SIZE; i++)
{
points[SIZE] = 0;
rebounds[SIZE] = 0;
assist[SIZE] = 0;
}
}
// Constructor #2
Constructor to accept parameter. Collects jersey number, name, team name, position, array of points for last 10 games, array of rebounds for last 10 games, array of assist for last 10 games.
PlayerData( int jn, string n, string t, string pos, int p[SIZE], int r[SIZE], int a[SIZE])
{
jnum = jn;
name = n;
team = t;
position = pos;
for (int i = 0; i < SIZE; i++)
{
points[SIZE] = p[SIZE];
rebounds[SIZE] = r[SIZE];
assist[SIZE] = a[SIZE];
}
}
// Mutator Function
void setJersery(int jn)
{
jnum = jn;
}
void setName(string n)
{
name = n;
}
void setTeam(string t)
{
team = t;
}
void setPosition(string pos)
{
position = pos;
}
void setPoints(int p[SIZE])
{
for (int z = 0; z < SIZE; z++)
{
points[SIZE] = p[SIZE];
}
}
void setRebounds(int r[SIZE])
{
for (int z = 0; z < SIZE; z++)
{
rebounds[SIZE] = r[SIZE];
}
}
void setAssist(int a[SIZE])
{
for (int z = 0; z < SIZE; z++)
{
assist[SIZE] = a[SIZE];
}
}
// Acessor methods
string getName()
{
return name;
}
int getJersey()
{
return jnum;
}
string getTeam()
{
return team;
}
string getPosition()
{
return position;
}
int getPoints()
{
return points[SIZE];
}
int getRebounds()
{
return rebounds[SIZE];
}
int getAssist()
{
return assist[SIZE];
}
/*
double averageP(int p[], const int SIZE);
double averageR(int r[], const int SIZE);
double averageA(int a[], const int SIZE);
*/
void averageP(int p[], const int SIZE);
void averageR(int r[], const int SIZE);
void averageA(int a[], const int SIZE);
double getAP()
{
return ap;
}
double getAR()
{
return ar;
}
double getAA()
{
return aa;
}
};
#endif // !PLAYERDATA_H
Calculates average points,rebounds, assist from the arrays that were passed.
PlayerData.cpp
#include "PlayerData.h"
using namespace std;
// Calculate average points
void PlayerData::averageP(int p[], const int s)
{
for (int c = 0; c < s; c++)
{
ap += p[c];
}
ap /= s;
//return ap;
}
// Calculate average rebounds
void PlayerData::averageR(int r[], const int s)
{
for (int c = 0; c < s; c++)
{
ar += r[c];
}
ar /= s;
//return ar;
}
// Calculate average assist
void PlayerData::averageA(int a[], const int s)
{
for (int c = 0; c < s; c++)
{
aa += a[c];
}
aa /= s;
//return aa;
}
Main
#include <iostream>
#include <iomanip>
#include "PlayerData.h"
using namespace std;
int main()
{
const int SIZE = 10;
int points[SIZE] = { 10,10,10,10,10,10,10,10,10,10 };
int assist[SIZE] = { 2,2,2,2,2,2,2,2,2,2, };
int rebounds[SIZE] = { 3,3,3,3,3,3,3,3,3,3 };
Here is where the problem occurs. The compiler marks under the 6 as if the int is not part of the arguments for the constructor. I'm not sure why it is doing this. I receive this message "No instance of constructor "PlayerData::PlayerData" matches the argument list."
PlayerData player1(6, "Jimmy Butler", "Chicago Bulls", "Forward", points[SIZE], rebounds[SIZE], assist[SIZE]);
getchar();
return 0;
}
Constructor requires an array of integers and in main you are passing a pointer to int. If you want to pass the whole array you should delete the [SIZE] because that is translated as (if SIZE is 5 for example) "give me the 6th element of 5 element array".
Try calling it like this.
PlayerData player1(6, "Jimmy Butler", "Chicago Bulls", "Forward", points, rebounds, assist);

[C++]Sorting objects by class member's value

In the code shown below, in the function void printExpensiveThanT(..) i'm supposed to print out the destination, distance and the price for the offers which are more expensive than the offer T in the function, sorted in ascending order by the distance value.
I'm not sure what should i use to sort them, i experimented something with vectors but it didn't work out so i deleted it.
Any help would be appreciated.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
class Transport {
protected:
char destination[100];
int basePrice;
int distance;
public:
Transport() {}
Transport(char *destination, int basePrice, int distance) {
strcpy(this->destination, destination);
this->basePrice = basePrice;
this->distance = distance;
}
virtual ~Transport() {}
virtual int priceTransport() = 0;
friend bool operator<(const Transport &t1, const Transport &t2) {
return t1.distance<t2.distance;
}
int getDistance(){ return distance; }
char *getDestination() { return destination; }
int getPrice() { return basePrice; }
};
class AutomobileTransport : public Transport {
private:
bool ifDriver;
public:
AutomobileTransport() {}
AutomobileTransport(char *destination, int basePrice,int distance, bool ifDriver) : Transport(destination,basePrice,distance) {
this->ifDriver = ifDriver;
}
void setIfDriver(bool ifDriver) {
this->ifDriver = ifDriver;
}
bool getIfDriver() {
return ifDriver;
}
int priceTransport() {
if(ifDriver) {
basePrice+=basePrice*20/100;
}
return basePrice;
}
friend bool operator<(const AutomobileTransport &a1, const AutomobileTransport &a2) {
return a1.distance<a2.distance;
}
};
class VanTransport: public Transport {
private:
int passengers;
public:
VanTransport() {}
VanTransport(char *destination, int basePrice, int distance, int passengers) : Transport(destination, basePrice, distance) {
this->passengers = passengers;
}
void setPassengers(int passengers) {
this->passengers = passengers;
}
int getPassengers() {
return passengers;
}
int priceTransport() {
for(int i = 0; i < passengers; i++) {
basePrice-=200;
}
return basePrice;
}
friend bool operator<(const VanTransport &k1, const VanTransport &k2) {
return k1.distance<k2.distance;
}
};
void printExpensiveThanT(Transport **offers,int n,AutomobileTransport &T) {
Transport *tmp;
for(int i = 0; i <= n; i++){
if(offers[i]->priceTransport() > T.priceTransport())
cout<<offers[i]->getDestination()<<" "<<offers[i]->getDistance()<<" "<<offers[i]->getPrice()<<endl;
}
}
int main() {
char destination[20];
int type,price,distance,passengers;
bool driver;
int n;
cin>>n;
Transport **offers;
offers=new Transport *[n];
for (int i=0; i<n; i++) {
cin>>type>>destination>>price>>distance;
if (type==1) {
cin>>driver;
offers[i]=new AutomobileTransport(destination,price,distance,driver);
} else {
cin>>passengers;
offers[i]=new VanTransport(destination,price,distance,passengers);
}
}
AutomobileTransport at("Ohrid",2000,600,false);
printExpensiveThanT(offers,n,at);
for (int i=0; i<n; i++) delete offers[i];
delete [] offers;
return 0;
}
Since you're dealing with pointers, the easiest thing to do is to use std::vector and std::sort:
#include <vector>
//...
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(),
[](Transport* left, Transport* right) { return *left < *right; });
// print out the values
for (auto it : sortedVect)
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
}
Also, your original code looped one more than it should (i <= n was wrong).
Edit:
If your compiler doesn't support the C++ 11 syntax, here is an alternate solution:
#include <vector>
//...
bool Sorter(Transport* left, Transport* right)
{ return *left < *right; }
void printExpensiveThanT(Transport **offers, int n, AutomobileTransport &T)
{
std::vector<Transport*> sortedVect;
for (int i = 0; i < n; i++)
{
if (offers[i]->priceTransport() > T.priceTransport())
sortedVect.push_back(offers[i]); // add this item to the vector
}
// sort the vector based on the dereferenced pointers and their respective
// operator <
std::sort(sortedVect.begin(), sortedVect.end(), Sorter);
// print out the values
std::vector<Transport*>::iterator it = sortedVect.begin();
while (it != sortedVect.end())
{
cout << (*it).getDestination() << " " << (*it).getDistance() << " " << (*it).getPrice() << "\n";
++it;
}
}