Trying to sort a vector of objects by any class me

2019-03-05 04:00发布

问题:

I am trying to figure out how to sort a vector of City objects. Each object has a cityName member and a cityCode member. I'd like for the accessor functions to automatically sort the vector then display it on the screen in the proper sorted order. I think I'm close, but can someone please tell me what I'm doing wrong? Thanks so much.

//specification file for the City class

#ifndef CITY_H
#define CITY_H
#include <string>

using namespace std;

class City
{
protected:
    string cityName;
    string cityCode;

public:
    //constructor
    City();
    City(string name, string code);

    //setter
    void setCityName(string name);
    void setCityCode(string code);

    //getter
    string getCityName();
    string getCityCode();


    bool SortByCityName(const City & c1, const City & c2)
    {
        return c1.cityName < c2.cityName;
    }

    bool SortByCityCode(const City & c1, const City & c2)
    {
        return c1.cityCode < c2.cityCode;
    }
};
#endif

//implementation file for the City class

#include "City.h"

//constructor
City::City()
{
    cityName = "";
    cityCode = "";
}

City::City(string name, string code)
{
    cityName = name;
    cityCode = code;
}


//setter
void City::setCityName(string name)
{
    cityName = name;
}

void City::setCityCode(string code)
{
    cityCode = code;
}


//getter
string City::getCityName()
{
    return cityName;
}

string City::getCityCode()
{
    return cityCode;
}

//specification file for the CityList class

#ifndef CITYLIST_H
#define CITYLIST_H
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "City.h"

using namespace std;

class CityList
{
private:
    vector<City> cities;

public:
    //constructor
    CityList();

    //setter
    void addCity(string name, string code);

    //getter
    void getCitiesByName();
    void getCitiesByCode();


    friend bool City::SortByCityName(const City & c1, const City & c2);
    friend bool City::SortByCityCode(const City & c1, const City & c2);

};
#endif

//implementation file for the CityList class

#include "CityList.h"

//constructor
CityList::CityList()
{
    cities.push_back(City("Atlanta          ", "GGG"));
    cities.push_back(City("Orlando          ", "FFF"));
    cities.push_back(City("Dallas/Fort Worth", "EEE"));
    cities.push_back(City("New York City    ", "DDD"));
    cities.push_back(City("Hawaii           ", "CCC"));
    cities.push_back(City("Chicago          ", "BBB"));
    cities.push_back(City("Los Angeles      ", "AAA"));
}


//setter
void CityList::addCity(string name, string code)
{
    cities.push_back(City(name, code));
}


//getter
void CityList::getCitiesByName()
{
    sort (cities.begin(), cities.end(), sortByCityName);
    for (City &c : cities)
        cout << "\t\t\t    " << c.getCityName() << "\t" << c.getCityCode() << endl;
}

void CityList::getCitiesByCode()
{
    sort (cities.begin(), cities.end(), sortByCityCode);
    for (City &c : cities)
        cout << "\t\t\t    " << c.getCityCode() << "\t\t" << c.getCityName() << endl;
}

回答1:

Your sort calls are using SortByCityName and SortByCityCode, but those are member functions not free-standing functions. The sort call doesn't call those as member functions on an object instance, so the member functions don't match the signature and it can't find them. You can fix this in two different ways: you can either take them out of the class altogether, or you can make them static members and use the class specifier e.g.

sort (cities.begin(), cities.end(), City::SortByCityName);

P.S. One trick I like to use in these situations is to have a single functor class that can sort by either criteria depending on a parameter.

struct CompareCities
{
    CompareCities(bool byName) : _byName(byName) {}
    bool operator()(const City & c1, const City & c2)
    {
        if (_byName)
            return c1.cityName < c2.cityName;
        else
            return c1.cityCode < c2.cityCode;
    }
    bool _byName;
};