Reputation: 163
I've got a problem when trying to create a sub class from an abstract class
class people
{
public:
people();
~people();
virtual int comparable(people*);
void order(people**,int);
};
my subclass
class worker : public people
{
private:
int salary;
public:
worker();
~worker();
int comparable (people*);
};
I need to order a dynamic array of people by salary (from worker) but i can't match a people array[j]=worker a;
What so you suggest? and then how do i call de function order? because a can't create a people object
Upvotes: 0
Views: 460
Reputation: 76240
I need to order a dynamic array of people by salary (from worker) but [...]. What do you suggest? and then how do I call the function
order
?
I'd consider refactoring your code. For a dynamic array I would use an std::vector
and for ordering you can use std::sort
.
If you want a decoupled system you should probably move the "container and sorting specific code" away from the person
and worker
class.
In fact it turns out that you don't even need a base class or public inheritance at all in this case. You can define a compare function for every class of your hierarchy. In particular for worker
:
bool compare(const worker &a, const worker &b) {
// return true if a is < b
// example follows
return a.salary < b.salary;
}
And finally, you are left with:
class worker {
// ...
};
std::vector<worker> workers;
and when you need to sort the workers
vector you can simply do:
std::sort(workers.begin(), workers.end(), compare);
If it makes sense to be able to do worker_a < worker_b
(even though discrimination based on the salary is not exactly a popular opinion) you could implement an operator<
:
struct worker {
bool operator<(const worker& rhs) {
// for example
return salary < rhs.salary
}
};
and just sort with:
std::sort(workers.begin(), workers.end());
Upvotes: 0
Reputation: 206557
Provide a pure virtual function to compare two people
.
#include <algorithm>
#include <utility>
#include <stdexcept>
class people
{
public:
people();
~people();
virtual int compare(const people* rhs) const = 0;
};
Implement the compare
function in worker
.
class worker : public people
{
private:
int salary;
public:
worker();
~worker();
virtual int compare(const people* rhs) const
{
const worker* rhsw = dynamic_cast<const worker*>(rhs);
if ( NULL == rhsw )
{
throw std::invalid_argument("rhs");
}
return (this->salary - rhsw->salary);
}
};
Provide a functor that you can use in std::sort
.
struct people_compare
{
bool operator()(people* lhs, people* rhs) const
{
return (lhs->compare(rhs) < 0);
}
};
Use std::sort
and the above functor to sort the list of people.
void order(people** plist, int num)
{
std::sort(plist, plist+num, people_compare());
}
Upvotes: 1
Reputation: 129314
Seems like a rather strange thing to do, and it would make more sense to have a salary
variable in people
if you are expected to sort some sort of collection of people
by their salary.
It's also not clear to me what the return value from comparable
is, but here's a solution that sorts based on salary
, and assumes that a people
object that isn't of worker
type (or derived thereof) has zero salary. It returns 0 for equal salary, 1 for "this object has greater salary than the passed in object" and -1 for "less salary than passed in object".
Note however that this is a pretty bad design, you shouldn't, typically, use dyanamic_cast
like this.
int worker::comparable(people *p)
{
worker *w = dynamic_cast<worker*>(p);
int wsalary = 0;
if (w)
wsalary = w->salary;
if (salary == wsalary) return 0;
if (salary > wsalary) return 1;
return -1;
}
Upvotes: 0