user3486836
user3486836

Reputation: 163

pure virtual class c++

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

Answers (3)

Shoe
Shoe

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

R Sahu
R Sahu

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

Mats Petersson
Mats Petersson

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

Related Questions