简体   繁体   中英

C++ vector sorting with my own Function

Info:
Parent Class: Vehicle
Child Class : Car & Lorry

I got a vector and i trying to sort it by ascending area

sort(myVector.begin(),myVector.end(),compareByArea);

so at the Vehicle.h

I did

class VehicleTwoD
{
private:
//some variable
public:
bool compareByArea(const VehicleTwoD,const VehicleTwoD);
}

and at Vehicle.cpp i did this

bool VehicleTwoD::compareByArea(const VehicleTwoD &a,const VehicleTwoD &b)
{
return a.getArea() < b.getArea();
}

Error was VehicleTwoD has no member named getArea.

It is located in my child Car & Lorry and double area is also declare in the child .

But the issue is if i want to sort by this way, could i achieve it by using virtual and then I create the same method at child but overload it and get my area sort by that way

Is there a better way to do it .

Thanks for all help!

Additional Info:

I have this getArea() function at Car & Lorry which is just a simple

double Car::getArea()
{ return area;}

double Lorry::getArea()
{ return area;}

But now as i got a list of object in my vector, each of them is a child of different class. but all got getArea function, i want to sort this vector which is

sortVector.assign(vehicletwod, vehicletwod + arrayCounter);
sort(sortVector.begin(),sortVector.end(),compareArea);

//but the sort doesnt work.

I don't know where to create compareArea which can getArea() of object 1 against object 2 and return bool result;

I try to create it in VehicleTwoD using this

bool VehicleTwoD::compareByArea(const VehicleTwoD &a,const VehicleTwoD &b)
{
return a.getArea() < b.getArea();
}

But the issue is VehicleTwoD don't have the function getArea, they are located at child. how should i get this fix . Thanks..

Thanks to the help:

I tried the following

template<typename T> bool compareByArea(const T &a, const T &b) {
    return a.getArea() < b.getArea();
}

and i declare it at the .h file too,

public:
template<typename T>
bool compareByArea(const T,const T);
virtual double getArea();

then at my main.cpp i tried

sortVector.assign(vehicletwod, vehicletwod + arrayCounter);
sort(sortVector.begin(),sortVector.end(),sortVector[0].compareArea);

It give me an error

error request for member compareByArea in sortVector.std::vector<_TP, _ALLOC ....... which is of non class type 'VehicleTwoD*'

If i do this

  sortVector.assign(vehicletwod, vehicletwod + arrayCounter);
  sort(sortVector.begin(),sortVector.end(),sortVector[0].compareArea);

I will get error compareByArea was not declared in this scope.

What should i do? I declared compareByArea at VehicleTwoD which is included in main.cpp

VehicleTwoD is the parent class, and i also virtual double getArea() so when it call getArea it will use the child getArea instead, because the private variable - area is at child and the function getArea() return area is also at child

What should i do.. confused & stuck. Thanks!

Latest Update Again:

I am trying to sort the vector by compareByArea which the smaller area will be sort at the highest while the bigger 1 will be at bottom.

The problem is getArea is a function of Car & Lorry (child class) and i create this compareByArea at main.cpp

sortVector is a vector copy of vehicletwod

The way i set value into my vehicletwod is this way..

if(vehicleType=="Car")
{
vehicletwod[arrayCount] = new Car();
vehicletwod[arrayCount].setDimension();
//set area
vehicletwod[arrayCount].setArea();
cout << "Done setting the data";
}

How do i achieve my sorting by area ascending.

I created this function at main.cpp

template<typename T> bool compareByArea(const T &a, const T &b) {
    return a.getArea() < b.getArea();
}

then i did this

sortVector.assign(vehicletwod, vehicletwod + arrayCounter);
sort(sortVector.begin(),sortVector.end(),compareByArea);

Compile Error: Compile error:

no matching function for call to 'sort(std::vector<VehicleTwoD*>::iterator, std::vector<VehicleTwoD*>::iterator, <unresolved overloaded function type>)'

note: template<class _RAIter> void std::sort (_RAIter, _RAIter)
note: template<class _RAIter, class _Compare> void std::sort(_RAiter, _RAIter, _Compare)

Thanks

I got a new compile error

error: passing 'const VehicleTwoD' as 'this' argument of 'virtual double VehicleTwoD::getArea()' discards qualifers.
error: passing 'const VehicleTwoD' as 'this' argument of 'virtual double VehicleTwoD::getArea()' discards qualifers.

Regarding my getArea is this

//in parent is this way

double VehicleTwoD::getArea()
{
double area;
area=0.00;
return area;
}

Car - Child is

 double Car::getArea()
    {
    return area;
    }

If VehicleTwoD::getArea is public, then the simplest thing to do is to make compareByArea a free function rather than a method of VehicleTwoD :

bool compareByArea(const VehicleTwoD &a,const VehicleTwoD &b) {
  return a.getArea() < b.getArea();
}

Then you can easily pass use it for sorting:

std::sort(myVector.begin(), myVector.end(), compareByArea);

In C++11, you could use a lambda expression:

std::sort(std::begin(myVector), std::end(MyVector),
          [](const VehicleTwoD &a, const VehicleTwoD &b) {
            return a.getArea() < b.getArea();
          });

If getArea is not public, you could still use compareByArea as a free function, but declare it as a friend of the class.

Update : A complete, working example:

#include <algorithm>
#include <iostream>
#include <vector>

class VehicleTwoD {
  public:
    VehicleTwoD(double area) : m_area(area) {}
    double getArea() const { return m_area; }
  private:
    double m_area;
};

bool compareByArea(const VehicleTwoD &a,const VehicleTwoD &b) {
  return a.getArea() < b.getArea();
}

int main() {
  std::vector<VehicleTwoD> vehicles;
  vehicles.push_back(VehicleTwoD(3.0));
  vehicles.push_back(VehicleTwoD(1.0));
  vehicles.push_back(VehicleTwoD(2.0));
  std::sort(vehicles.begin(), vehicles.end(), compareByArea);
  for (auto it = vehicles.begin(); it != vehicles.end(); ++it) {
    std::cout << it->getArea() << std::endl;
  }
  return 0;
}

Make a template function:

template<typename T> bool compareByArea(const T *a, const T *b) {
    return a->getArea() < b->getArea();
}

then you can pass it to sort:

sort(sortVector.begin(), sortVector.end(), compareByArea<VehicleTwoD>);

Update:

Vehicle.h:

class VehicleTwoD {
...
public:
    virtual double getArea() const;
};

template<typename T> bool compareByArea(const T *a, const T *b) {
    return a->getArea() < b->getArea();
}

main.cpp:

#include "Vehicle.h"
#include <vector>
...
std::vector<VehicleTwoD*> sortVector;
// fill sortVector
sort(sortVector.begin(), sortVector.end(), compareByArea<VehicleTwoD>);
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM