Sort vector of object pointers - c++

I'm creating a c++ program of a race.
I have the race class. Each race has a name, a distance and vector of results pointers(its a result for each participant).
The result class has a pointer to the participant and a time.
The class time has hours, minutes and seconds.
I want to sort the vector of results from the fastest time to the slowest, so to compare results I created the function bool operator <(Result& res2) const in the class result.
All the functions in the .h file are implemented, I'm just not showing them all.
I'm almost certain that the function sortResults is not right but the function operator< is giving me errors that I don't know how to solve. It gives me this error in all the if statements: Multiple markers at this line
- passing 'const Time' as 'this' argument of 'unsigned int Time::getHours()' discards qualifiers [-
fpermissive]
- Line breakpoint: race.cpp [line: 217]
- Invalid arguments ' Candidates are: unsigned int getHours() '
Can you tell me what I'm doing wrong?
.h file:
class Time
{
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
public:
Time(unsigned int h, unsigned int m, unsigned int s, unsigned int ms);
Time();
unsigned int gethours();
unsigned int getMinuts();
unsigned int getSeconds();
string show();
};
class Participant {
string name;
unsigned int age;
string country;
public:
Participant(string n, unsigned int a, string c);
string getName();
string getCountry();
int getAge();
string show() const;
};
class Result {
Participant *part;
Time time;
public:
Result(Participant *p, Time t);
Participant *getParticipant() const;
Time getTime();
string show();
bool operator <(Result& res2) const;
};
class Race {
string name;
float distance;
vector<Result *> results;
public:
Race(string nm, float dist);
string getName();
void setName(string nm);
float getDistance();
vector<Result *> sortResults();
void addResult(Result *r);
string showRaceResults();
string show();
};
.cpp file:
bool Result::operator <(Result& res2) const {
if (time.gethours() < res2.getTime().gethours())
return true;
else {
if (time.gethours() > res2.getTime().gethours())
return false;
else {
if (time.getMinutes() < res2.getTime().getMinutes())
return true;
else {
if (time.getMinutes() > res2.getTime().getMinutes())
return false;
else {
if (time.getSeconds() < res2.getTime().getSeconds())
return true;
else {
return false;
}
}
}
}
}
}
vector<Result *> Race::sortResults() {
sort (results.begin(), results.end(), operator <);
return results;
}

You should declare and define Time::gethours() as constant member function.
class Time {
// ...
unsigned int gethours() const; // note the "const"
};
unsigned int Time::gethours() const { /* ... */ } // note the "const"
To sort vector<Result*>, you need to
Change Result::operator<() to take const Result& rather than Result& as parameter
Define a comparison function for Result* which looks like static bool cmpResultPtr(const Result* lhs, const Result* rhs) { return *lhs < *rhs; }
Call sort(results.begin(), results.end(), cmpResultPtr);
The function cmpResultPtr() could be defined in the .cpp file, before the definition of Race::sortResults().

You declare operator< to be const but Time::getHours, which it calls, doesn't have the same declaration. To the compiler, this means getHours could change the value of the time member which violates the constness of operator<.

Related

C++ Cohesion with class Date

I'm preparing for an exam of c++. In the last test I failed the cohesion between a class that had the Date date_event as a variable.
How to create different constructors of class P if the class P need an object Data to create an object of the class( the one with no parameters, the one with all the parameters and the copy constructor)?
Also i didn't write this Date actual class. Is it correct to write constructors like that ?
How should giorno(0) , month(0) etc work properly ?
(giorno=day, mese=month, anno= year)
#ifndef DATA_H
#define DATA_H
#include <iostream>
#include <cstring>
using namespace std;
class Data{
friend ostream& operator<<(ostream&, const Data&);
friend istream& operator>>(istream&, Data&);
protected:
int giorno;
int mese;
int anno;
public:
Data(): giorno(0), mese(0), anno(0){}
Data(const int& g, const int& m, const int& a): giorno(g), mese(m), anno(a){}
Data(const Data& D) : giorno(D.giorno), mese(D.mese), anno(D.anno){}
//...
};
#include "Data.h"
class P{
protected:
Data birthday;
public:
P();
P(const int, const int, const int); //i should pass day, month, year right?
P(const P&);
}
Well the question is not clear, but several things can be said.
General
Avoid using namespace std; and use the namespace directly. E.g. friend std::ostream& operator<<(std::ostream&, const Data&);
I suppose this is not the original code, but just in case : don't forget your header guards #ifndef CLASSNAME_H, #define CLASSNAME_H & #endif /* CLASSNAME_H */
Date class
You can implement the constructor that way, but prefer implementing them in the .cpp file.
It is unnecessary to pass the integer parameters as references. Use this for big parameters, from strings to whole objects.
Prefer English for code, even if your colleagues/reviewers/professors are not English. It is always preferred in computer science. This is valid for variable/function names, but also for comments.
P(erson) class
Give your parameters names. Often people that will use your code will only read the headers, so the headers must be as self-explanatory as possible.
For the P contractor, try this :
class Date {
public:
Date(const int pDay, const int pMonth, const int pYear);
Date(const Date &pDate);
/* Getters */
int day(void) const;
int month(void) const;
int year(void) const;
/* Setters */
void setDay(const int pDay);
void setMonth(const int pMonth);
void setYear(const int pYear);
protected:
int mDay;
int mMonth;
int mYear;
};
class Person {
public:
Person(const int pDay, const int pMonth, const int pYear);
Person(const Person &pPerson);
/* Getters */
Date birthday(void) const;
/* Setters */
void setBirthday(const int pDay, const int pMonth, const int pYear);
void setBirthday(const Date &pDate);
protected:
Date mBirthday;
};
Date::Date(const int pDay, const int pMonth, const int pYear):
mDay(pDay),
mMonth(pMonth),
mYear(pYear)
{
/* Empty */
}
Date::Date(const Date &pDate) :
mDay(pDate.day()),
mMonth(pDate.month()),
mYear(pDate.year())
{
/* Empty */
}
int Date::day(void) const {
return mDay;
}
int Date::month(void) const {
return mMonth;
}
int Date::year(void) const {
return mYear;
}
/* Setters */
void Date::setDay(const int pDay) {
mDay = pDay;
}
void Date::setMonth(const int pMonth) {
mMonth = pMonth;
}
void Date::setYear(const int pYear) {
mYear = pYear;
}
Person::Person(const int pDay, const int pMonth, const int pYear):
mBirthday(pDay, pMonth, pYear)
{
/* Empty */
}
Person::Person(const Person &pPerson):
mBirthday(pPerson.birthday().day(), pPerson.birthday().month(), pPerson.birthday().year())
{
/* Empty */
}
Date Person::birthday(void) const {
return mBirthday;
}
void Person::setBirthday(const int pDay, const int pMonth, const int pYear) {
mBirthday.setDay(pDay);
mBirthday.setMonth(pMonth);
mBirthday.setYear(pYear);
}
void Person::setBirthday(const Date &pDate) {
mBirthday.setDay(pDate.day());
mBirthday.setMonth(pDate.month());
mBirthday.setYear(pDate.year());
}
Please note that there are lots of ways to do this in a prettier fashion, and with less data copies.

Sorting vector objects with accessor

This is part of a C++ program based on the Alternative Vote electoral method, using VS2015. I have a class for Party
#pragma once
#ifndef _PARTY_H
#define _PARTY_H
#include <string>
class Party {
public:
Party();
~Party();
Party(std::string n, int pos);
void reset();
void upTotal();
int getPosition();
std::string getName();
int getVotes();
private:
std::string name;
int votes;
int position;
};
#endif
and
#include <iostream>
#include "Party.h"
using namespace std;
Party::Party() {}
Party::~Party() {}
Party::Party(string n, int p) {
name = n;
position = p;
}
void Party::reset() {
votes = 0;
}
void Party::upTotal() {
votes += 1;
}
int Party::getPosition() {
return position;
}
string Party::getName() {
return name;
};
int Party::getVotes() {
return votes;
}
I tried to sort on votes received using (calculated from ballot papers elsewhere in the program
void sortParties() {
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)
{
return a.getVotes() < b.getVotes();
});
}
which returned illegal operand errors. Moving the variables from private to public and writing the following did work
void sortParties() {
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)
{
return a.votes < b.votes;
});
}
which gets it working, but I want to write it with proper encapsulation using private variables and an accessor for votes. Do I need to overload somehow, or convert type?
You have the following functions defined:
int getPosition();
std::string getName();
int getVotes();
They should probably all be const; ie
int getPosition() const;
std::string getName() const;
int getVotes() const;
This will allow you to call the functions from your const object at
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)

C++, Constructors: Out-of-line definition of 'class' does not match any declaration in 'class'

So I was trying to program a target heart rate calculator in C++ and when I tried to build it, this error was returned. Just to let you know, I am instructed to separate the implementation and interface.
Here's the interface
#include <iostream>
#include <string>
class HeartRates
{
public:
// constructor initialize HeartRates
HeartRates( std::string, std::string, int, int, int );
// Setting each variable
void setFirstName( std::string );
void setLastName( std::string );
void setdobMonth( int );
void setdobDay( int );
void setdobYear( int );
void setCurrentYear( int );
std::string getFirstName() const;
std::string getLastName() const;
int getdobMonth() const;
int getdobDay() const;
int getdobYear() const;
int getCYear() const;
int getAge() const;
int getMaximumHeartRate() const;
int getTargetHeartRate() const;
private:
std::string firstName;
std::string lastName;
int dobMonth;
int dobDay;
int dobYear;
int currentYear;
};
And here's the implementation
#include <iostream>
#include <string>
#include "HeartRates.h"
using namespace std;
// constructor that initializes all the stuff
This is the line that is giving me this error: Out-of-line definition of 'HeartRates' does not match any declaration in 'HeartRates'
HeartRates::HeartRates( string first, string last, int M, int D, int Y, int cY )
{
setFirstName( first );
setLastName( last );
setdobMonth( M );
setdobDay( D );
setdobYear( Y );
setCurrentYear( cY );
}
Continue on with the code
// set functions
void HeartRates::setFirstName( string first )
{
firstName = first; // store the first name in the object
}
void HeartRates::setLastName( string last )
{
lastName = last; // store the last name in the object
}
void HeartRates::setdobMonth( int M )
{
dobMonth = M; // store the month of birth in the object
}
void HeartRates::setdobDay( int D )
{
dobDay = D; // store the day of birth in the object
}
void HeartRates::setdobYear( int Y )
{
dobYear = Y; // store the year of birth in the object
}
void HeartRates::setCurrentYear( int cY )
{
currentYear = cY;
}
// get functions
string HeartRates::getFirstName() const
{
return firstName; // return user's first name
}
string HeartRates::getLastName() const
{
return lastName; // return user's last name
}
int HeartRates::getdobMonth() const
{
return dobMonth;
}
int HeartRates::getdobDay() const
{
return dobDay;
}
int HeartRates::getdobYear() const
{
return dobYear;
}
int HeartRates::getCYear() const
{
return currentYear;
}
// Functions
int HeartRates::getAge() const
{
int age;
age = currentYear-dobYear;
return age;
}
int HeartRates::getMaximumHeartRate() const
{
int maxHeartRate;
maxHeartRate = 220 - getAge();
return maxHeartRate;
}
int HeartRates::getTargetHeartRate() const
{
int targetHeartRate;
targetHeartRate = getMaximumHeartRate() * 0.85;
return targetHeartRate;
}
Sorry for the formatting and copy and pasting everything. Newbie here, I just don't know which part of the code went wrong.
HeartRates( std::string, std::string, int, int, int );
2 strings and 3 int.
HeartRates::HeartRates( string first, string last, int M, int D, int Y, int cY )
2 strings and 4 int.
I had a similar issue today and my fix was slightly different, so I'll throw this here in case it ever helps anyone in the future. I had forward declared a class OUTSIDE of the appropriate namespace in the header, so my error looked something like this:
1. Type of 1st parameter of member declaration does not match definition
'const std::shared_ptr<MyClass> &' (aka 'const shared_ptr<MyClass> &') vs
'const std::shared_ptr<MyClass> &' (aka 'const shared_ptr<myNamespace::MyClass> &'))
The solution for me was to forward declare that class inside the namespace, rather than outside it.
Bad:
class MyClass;
namespace myNamespace {
}
Good:
namespace myNamespace {
class MyClass;
}

C++ - global variable scope

I have some task: There are a lot of .cpp files, so I must find all the declarations of global variables in each of them. So I have, for example, this part of code:
class word {
public:
word(string code0, string text0, int weight0) : code(code0), text(text0),
weight(weight0), index(word::num) {};
friend bool operator<(word w1, word w2);
friend ostream &operator<<(ostream &stream, word w);
friend bool wordWithCode::operator()(const word &w);
static bool convertChars(char *inp, char *out);
inline bool checkCode(char *check) { return !strcmp(code.c_str(),check); };
inline const char* getText() { return text.c_str(); };
inline void useIt(set< word >::iterator &i) {
cout << this->text;
if (code[0]!='1') {
word::num++;
word::words.insert(word(this->code,this->text,this->weight+1));
word::words.erase(i);
}
return;
};
static set< word > words;
string code;
string text;
int weight;
static int num;
private:
int index;
};
int word::num = 0;
set< word > word::words;
int main(){
...
return 0;
}
So my question: Is the static variables word::num and word::words are global? And how to correctly identify their names(just "num" or "word::num")?
Yes, they're single global variables and you reference them outside of word's functions as word::num and word::words. Inside word's functions you can reference them just as num and words

expecting primary expression before token in c++

Here is the problem:
In console.cpp
void Console::PrintMedicine(Medicine* m){
int ID = Medicine.getID(); //here i get the error expecting primary expression before "." token, it doesn't work with -> either
cout<<"The Medicine's ID is: ";
cin>>ID;
}
class Medicine:
what's private:
private:
int ID;
std::string nume;
double concentratie;
int cantitate;
what's public
public:
Medicine(); //implcit constructor
Medicine(int ID, std::string nume, double concentratie, int cantitate);//constructor with parameteres
~Medicine(); //destructor
//the getID function
const int& Medicine::getID() const{
return this->ID;
}
//the getName function
const std::string& Medicine::getName() const{
return this->nume;
}
//the getConcentration function
const double& Medicine::getConcentration() const{
return this->concentratie;
}
//the getQuantity function
const int& Medicine::getQuantity() const{
return this->cantitate;
}
The expression Medicine.getID() is incorrect. Medicine is the name of a class, and you can't use the dot operator to access its members. First, you need an instance of Medicine whose members you want to access; second, if you have a pointer to that instance, you need to use the arrow operator (operator ->).
Therefore, it should be:
void Console::PrintMedicine(Medicine* m){
int ID = m->getID();
// ^^^
// ...
}