overloaded operators - compare strings

as part of an assignment, i have to add an overloaded operator as a member function to a base class which will compare 'people objects' according to their name, and then sort the names alphabetically. the person objects are as follows:

1
2
3
4
5
6
7
8
9
10
11
12
        Person person1("Brian");
	Person person2("Adam");
	Person person3("Ciaran");
	Person person4("Peter");
	Person person5("Mary");

	Person *ptrArray[5];
	ptrArray[0] = &person1;
	ptrArray[1] = &person2;
	ptrArray[2] = &person3;
	ptrArray[3] = &person4;
	ptrArray[4] = &person5;


i've tried to add this to my person.h class, but i'm getting an error saying 'too many parameters for this operator function'?:

bool operator < (const string& lhs, const string& rhs);

could someone show me how to implement the overloaded operator so as to compare the names and sort them alphabetically? we've been hinted to look at the compare method of the string class - how can this work with the operator?
If you've put that operator inside a class, the first argument is this. Example
1
2
3
4
5
6
struct Foo{
   std::string name;
   bool operator < (const Foo& f) {
      return name < f.name;
   }
};
i don't really get why i need to use an overloaded operator here if my ultimate goal is sort an array of pointers to Person objects, in alphabetical order based on 'name'??
If you declare/define outside of the class, your function header is correct Otherwise, it will only take one parameter (the right side). The classes object on the left is implied.

To answer your second question: How else would you sort them? I suppose you could do it in a function, but this method is just as good and may even be easier to read.
thanks for clearing that up. i found it a bit confusing because in the labsheet we are to "add appropriate overloaded operators as member functions" and then "order them
alphabetically". so i was thinking that this had to be done in two steps using the overloaded operator and then some sorting algorithm.

how would i go about using the overloaded operator to sort the 5 names in prtArray? i'm not looking for the exact answer but i havn't much experience using them, so a point in the right direction would be helpful.
Are you supposed to write your own sorting algorithm or can you use std::sort? Either way, since the array is an array of pointers this will be slightly tricky. You should write
1
2
3
bool less(Person* a, Person* b) {
   return *a < *b;
}
even though it's a bit silly..
it doesn't specify what to use in the labsheet, so i suppose i could use std::sort, though i do i have notes on bubble, select sort etc.

we have to use an overloaded operator as a member function - could you tell me why i'm being asked to do this when i could just use a sorting algorithm?

this is what i have in my .h file:

bool operator < (const Person& p) { return name < p.name; }

do i still need to implement the overloaded function in my Person.cpp file? i've tried to do it but get an error saying "an operator must be declared as a function...?

i've put this in Main.cpp...

1
2
3
4
for(int i = 0; i < 5; i++) 
	{
		bool operator<( const Person&, Person ptrArray[] );
	}


but it doesn't seem to be up to much. am i on the right track? it doesn't seem right to me...i'm lost to be honest!
we have to use an overloaded operator as a member function - could you tell me why i'm being asked to do this when i could just use a sorting algorithm?


sort algorithms inevitably compare one element to another element. What does operator< do again? Oh yeah! It compares one Person with another Person. Worthy of note: simply defining an overloaded operator< for Person makes std::sort usable on arrays composed of Persons.

Unless your assignment requires it, I wouldn't use an array of pointers to Person. Doing so is likely to cause you grief.

The following should put you on the right track. The overloaded operator< is used in line 22.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <string>

class Person {
	std::string name ;

public:
	Person() {}
	Person(char const* n) : name(n) {}

	bool operator<(const Person& p) const
	{return name < p.name;}
};

const unsigned n_persons = 5 ;

unsigned find_smallest(Person*p, unsigned size)
{
	unsigned smallest = 0 ;

	for (unsigned cur_per=1; cur_per < size;  ++cur_per)
		if ( p[cur_per] < p[smallest] )
			smallest = cur_per ;

	return smallest ;
}

int main()
{
	Person person[n_persons] ;

	person[0] = "Brian" ;
	person[1] = "Adam" ;
	person[2] = "Ciaran" ;
	person[3] = "Peter" ;
	person[4] = "Mary" ;

	unsigned first = find_smallest(person, n_persons) ;

	std::cout << "The number " << first+1 << " person in the array is the first, alphabetically.\n" ;
}



Last edited on
thanks for the well explained reply. unfortunanetely we do have to use an array of pointers. you mentioned std::sort being usable for an array of Persons. would this apply for an array of pointers to Person objects also?

i had a similar problem in my previous labsheet with an array of pointers, but i just copied the necessary data into a temporary array of the same data type and then sorted it from there. what would be involved when using an array of pointers?
You cannot compare two Person* with an operator written for Person. Nor can you overload the operator for Person*. The solution is to write a function like I showed (you might want to check for NULL in it though). std::sort can use a function instead of operator < if you pass one. See the reference.
hamsterman i didn't know you couldn't compare in that way using an operator. i'm just going by what it says on the labsheet, which is:

7. Now add appropriate overloaded operators as member functions to the Person
class which will enable you to compare and order people according to their name.
(check out the compare method of the string class)

8. Add code to your main method to enable you to create 3 (or more) Person
objects, store pointers to them in an array of pointers to Person, and order them
alphabetically.


maybe i'm reading the instructions wrong? or is what i'm being asked to do not possible?

i tried to code a sortArray function which copies relevant data to temp array, orders it alphabetically, then puts it back in the prtArray, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void sortArray(Person ptrArray[], int n)
{
	string tempArray[5];
	for(int i = 0; i < 5; i++)
		tempArray[i] = ptrArray[i].getName();

	int smallest  = 0;

	for(int currPer = 1; currPer < n; currPer++)
	{
		if(tempArray[currPer] < tempArray[smallest]) 
			smallest = currPer;
		//return smallest;
	}

	for(int i = 0; i < 5; i++)
		ptrArray[i] = tempArray[i];
}


then call it in main, and print out as follows:

1
2
3
4
sortArray(*ptrArray, 5);

	for(int i = 0; i < 5; i++)
		cout<<ptrArray[i]->getName()<<endl;


but i'm getting one of those f*cking
Unhandled exception at 0x00831fdb in Lab 2.exe: 0xC0000005: Access violation reading location 0xccccccd0.
errors...
1
2
3
4
5
void sortArray(Person ptrArray[], int n)

....

sortArray(*ptrArray, 5);


See, this is what I meant about the pointers causing you grief.

Look at the prototype of SortArray for a second. It expects an array of Person and an int that tells it how many Person objects are in the array.

Now look at what you gave it. *ptrArray points to a single Person, and you're telling sortArray that there are 5 Person objects pointed to. So, obviously, it ends up accessing memory it shouldn't.

You need to change sortArray to work on an array of pointers to Person.

1
2
3
4
5
void sortArray(Person* ptrArray[], int n)

or 

void sortArray(Person** ptrArray, int n)


are functionally equivalent.
okay i understand what you mean by that. i have sortArray delcared as:

void sortArray(Person** ptrArray, int n);

first line of implementation:

1
2
void sortArray(Person ptrArray[], int n)
{...}


and a call to it:

sortArray(ptrArray, 5);

(this is the only way it won't give me an 'underlined' error before i compile...

but it won't compile despite the above and i'm getting an error:

Error 1 error C2664: 'sortArray' : cannot convert parameter 1 from 'Person *' to 'Person **


any ideas?
The definition of the function must match the declaration.

Here's a version that uses std::sort, just to get it working and then you can fill in your own code for the sort.
(the call in main is correct)
1
2
3
4
5
6
7
8
9
10
11
#include <sort>

...

bool less_than( Person * p1, Person *p2 )
{ return *p1 < *p2; }  // here's that overloaded operator!

void sortArray(Person ** ptrArray, int n)
{
	std::sort(ptrArray, ptrArray+n, less_than) ;
}



excellent, working now, thanks a lot
Topic archived. No new replies allowed.