C++ virtual function passing and factory function - c++

I'm struggling with the last part of a homework problem and I'm getting the error
error: passing ‘const string {aka const std::__cxx11::basic_string<char>}’ as ‘this’ argument discards qualifiers [-fpermissive]
nm = name_str;
The constructor in question is
Pilot::Pilot(std::string name_str): Aircrew(nm)
{
nm = name_str;
};
with factory function
Aircrew *Aircrew::makeAircrew(char ch, std::string name_str){
if(ch == 'P')
return new Pilot(name_str);
in the header file I have
class Aircrew
{
public:
Aircrew(std::string name_str);
virtual const std::string type(void) const = 0;
virtual const int maxFlights(void) const = 0;
const double maxHours(void) const;
const std::string name(void) const;
void setFlights(int i);
void setHours(double h);
void print(void) const;
virtual void scheduleFlight(int f, double h) const;
static Aircrew* makeAircrew(char ch, std::string name_str);
virtual ~Aircrew(void);
protected:
const std::string nm;
int flightsTaken;
double hoursWorked;
};
class Pilot: public Aircrew
{
public:
Pilot(std::string name_str);
virtual const std::string type(void) const;
virtual const int maxFlights(void) const;
};
Now per the factory function I'm trying to pass a name along to the const nm string but I'm struggling with how to do that. I've been googling to no avail. The goal is to pass name_str to nm so that in the member function name i can do.
const string Aircrew::name(void) const{
return nm;
}
Note: I can't change anything in the header files as per the professor. Thank you in advance!

Related

Passing variables to a constructor with multiple inheritance

I am having problems passing up two pieces of data through my classes, ID and Name specificly. I understand that you cannot call the base class constructor up without going through the previous parent classes but I am struggiling to fiugure out why this is not working, do I need constructors all the way up or can I just add it on at the end of my class creation like the base class?
Thanks in advance.
class CEmployee
{
private:
char m_name[30];
char m_id[30];
//virtual float Pay() { return 0;}; // virtual function
virtual float Pay() = 0; // pure virtual function
public:
CEmployee(char name[], char id[])
{
strcpy_s(m_name, name);
strcpy_s(m_id, id);
}
CEmployee()
{
strcpy_s(m_name, "");
strcpy_s(m_id, "");
}
void PrintCheck()
{
cout << m_name << " " << Pay() << endl;
}
};
class CFulltimeEmployee : public CEmployee
{
protected:
static float m_benefitcost;
public:
CFulltimeEmployee()
{
}
CFulltimeEmployee(char name[], char id[]) : CEmployee (name, id)
{
m_benefitcost = 100;
}
};
float CFulltimeEmployee::m_benefitcost = 100;
class CHourlyFTEmployee : public CFulltimeEmployee
{
private:
float m_rate;
float m_hours;
public:
CHourlyFTEmployee()
{
}
CHourlyFTEmployee(const char name[], const char id[], float rate, float hours) : CFulltimeEmployee
(name, id)
{
m_rate = rate;
m_hours = hours;
}
float Pay()
{
return m_rate * m_hours - m_benefitcost;
}
};
Errors
Error (active) E0289 no instance of constructor "CFulltimeEmployee::CFulltimeEmployee" matches the argument list
Error C2664 'CFulltimeEmployee::CFulltimeEmployee(char [],char [])': cannot convert argument 1 from 'const char []' to 'char []' Project9
Writing a minimal reproducible example really isn't that hard; you remove whatever isn't needed while still demonstrating the problem. In this case, it might be:
class CEmployee
{
char m_name[30];
char m_id[30];
virtual float Pay() = 0; // pure virtual function
public:
CEmployee(char name[], char id[])
{
strcpy_s(m_name, name);
strcpy_s(m_id, id);
}
};
struct CFulltimeEmployee : public CEmployee
{
CFulltimeEmployee(char name[], char id[]) : CEmployee(name, id) { }
};
struct CHourlyFTEmployee : public CFulltimeEmployee
{
CHourlyFTEmployee(const char name[], const char id[]) : CFulltimeEmployee(name, id) { }
float Pay() override { return 0.0; }
};
In particular, notice that none of m_benefitcost, m_rate or m_hours are needed; nor is PrintCheck(). (class is private by default while struct is public; this also helps to reduce noise.)
Once you've done that, it's very easy to see the problem the compiler is complaining about
error C2664: 'CFulltimeEmployee::CFulltimeEmployee(char [],char [])': cannot convert argument 1 from 'const char []' to 'char []'
In CHourlyFTEmployee, you've written const char name[] (and const char id[]); but the base class (CFulltimeEmployee) is char name[]—no const. Data that is const can't "easily" be assigned to non-const data; the "fix" is straight-forward: remove the const:
CHourlyFTEmployee(char name[], char id[]) : CFulltimeEmployee(name, id) { }`
The sample still has other issues, but it sounds like you're stuck with the existing CEmployee base class.
An even better solution is to hide as much of the legacy CEmployee class as possible; maybe by introducing another class CEmployeeNew (or CEmployee2); that might look like:
struct CEmployeeNew : public CEmployee
{
CEmployeeNew(const std::string& name, const std::string& id) :
CEmployee(const_cast<char*>(name.c_str()), const_cast<char*>(id.c_str())) { }
};

c++ custom comprator for more than attribute

I am trying to implement a naive File System.
I have this class
class BaseFile {
private:
string name;
public:
BaseFile(string name);
string getName() const;
void setName(string newName);
bool operator < (const BaseFile& str) const;
bool operator > (const BaseFile& str) const;
virtual int getSize() = 0;
};
and the subclass
class Directory : public BaseFile {
private:
vector<BaseFile*> children;
Directory *parent;
public:
Directory(string name, Directory *parent); r
Directory *getParent() const;
void setParent(Directory *newParent);
void removeFile(string name);
void removeFile(BaseFile* file);
void sortByName();
bool SortSize(BaseFile& a , BaseFile& b);
void sortBySize();
vector<BaseFile*> getChildren(); n
int getSize();
string getAbsolutePath();
};
I need to sort the vector<BaseFile*> children once by the attribute size by activating the function SortBySize().
And by name by the function SortByName().
I cant use sort algorithm I want to use std::sort()
For the names I overloaded the operators < > and for the numbers(size) I want to define a custom comparison function.
I defined the function in the class Directory. I tried to make is static it didn't work
bool Directory::SortSize(BaseFile& a , BaseFile& b)
{
return (a.getSize() < b.getSize());
}
but when I use std::(children.begin(), children.end(), sortSize)
I get "invalid use of non-static member function".
Any help?
To sort by size using a lambda expression:
vector<BaseFile*> files;
std::sort(files.begin(), files.end(),
[](const BaseFile* a, const BaseFile* b)
{ return a->getSize() < b->getSize(); });

How to erase an element from a vectors vector?

i have a problem to delete an "Member" from a "Group" by index:
#include <vector>
#include <string>
using namespace std;
class Member
{
public:
explicit Member(const string &name, const unsigned long &key) : m_name(name), m_key(key) {}
const string &getName() const {return m_name;};
const unsigned long &getKey() const {return m_key;};
private:
string m_name;
unsigned long m_key;
};
//------------------------------------------------------------------------
class Group
{
public:
explicit Group(const string &name) : m_name(name) {}
const string &getName() const {return m_name;};
void addMember(const Member &member) {m_member.push_back(member);};
const vector<Member> &getMember() const {return m_member;};
private:
string m_name;
vector<Member> m_member;
};
void main() {
vector<Group> group;
group.push_back(Group("Membergroup 1"));
group[0].addMember(Member("Mark", 123456));
group[0].addMember(Member("John", 234567));
group[0].getMember().erase(group[0].getMember().begin() + 1); //to delete John
}
Error: : passing 'const std::vector' as 'this' argument discards qualifiers [-fpermissive] group[_group].getMember().erase(group[_group].getMember().begin() + 1);
Can someone help me please?
The problem is here:
const vector<Member> &getMember() const {return m_member;};
The function getMember() (which I suggest to call as getMembers()) returns a const reference to the vector.
Since constness, the compiler prevents modifications.
You can fix just refactoring in the following way:
class Group
{
public:
// ...
const vector<Member>& getMembers() const { return m_member; }
vector<Member>& getMembers() { return m_member; }
// ...

qlist with custom class unable to append

I've seen other questions on here, but they deal with pointers, or with qobject derived classes, so they didn't seem relevant.
I am trying to append values into a qlist of custom classes, here is the class
class matchPair
{
public:
matchPair(int a=0, int b=0)
: m_a(a)
, m_b(b)
{}
int a() const { return m_a; }
int b() const { return m_b; }
bool operator<(const matchPair &rhs) const { return m_a < rhs.a(); }
// matchPair& operator=(const matchPair& other) const;
private:
int m_a;
int m_b;
};
class videodup
{
public:
videodup(QString vid = "", int m_a = 0, int m_b = 0);
~videodup() {}
QString video;
bool operator==(const QString &str) const { return video == str; }
// videodup& operator=(QString vid, int m_a, int m_b);
QList<matchPair> matches;
};
struct frm
{
QString file;
int position;
cv::Mat descriptors;
QList<videodup> videomatches;
};
QList<frm> frames;
and the line that fails is:
frame.videomatches.at( frame.videomatches.indexOf(vid) ).matches.append(pair);
the error I get is:
/usr/local/Cellar/qt5/5.5.1_2/lib/QtCore.framework/Headers/qlist.h:191: candidate function not viable: 'this' argument has type 'const QList<matchPair>', but method is not marked const
void append(const T &t);
^
what am I doing wrong?
You are trying to append a value to a const QList<T>, which means your QList<T> is constant, i.e. non-mutable. Look closely, the error reads this has type const QList<matchPair>, and you can only call const methods on a const object, while append() obviously is not const both syntactically and semantically. Fix the QList<matchPair> to not be const.
Edit 2:
Having looked closer at the code, here is the culprit, indeed:
frame.videomatches.at( frame.videomatches.indexOf(vid) ).matches.append(pair);
^^
QList<T>::at() returns const T&, which leads to the problem I've described above. Use QList<T>::operator[]() insdead,which has overloads that return both a const T and T values.
Edit:
However, which compiler brand and version is this? I can't reproduce this error message in g++ by calling a non-const method on a const class object, both templated and non-templated (I am getting an error, but it's worded differently).

What this const before method name mean?

In one of our text-books it is suggested that we should use interfaces in C++ as a good design practice. They give below example;
class IAnimation
{
public:
virtual void VAdvance(const int deltaMilisec) = 0;
virtual bool const VAtEnd() const = 0;
virtual int const VGetPostition() const = 0;
};
I did not get the meaning of:
virtual bool const VAtEnd() const = 0;
virtual int const VGetPostition() const = 0;
I know const is used after () to make them invocable from const instances. But what const before VAtEnd and VGetPosition (method names) mean?
Thank you.
It means the return type is const, it's the same as:
virtual const bool VAtEnd() const = 0;
virtual const int VGetPostition() const = 0;
It has no practical meaning though, as the return value is copied anyway.
If you'd be returning an object though:
struct A
{
void goo() {}
};
const A foo() {return A();}
int main()
{
A x = foo();
x.goo(); //ok
foo().goo(); //error
}