Using multiple, overloaded operators at once?

Hello everybody,

I'm currently learning C++ and I wanted to overload an operator for the following class, that should count the amount of a specific character in various strings:

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
42
#include <iostream>
using namespace std;

class Counter
{
private:
	int* amounts;
	char first;
	char last;
public:
	Counter(char first='a',char last='z');
	virtual ~Counter(){delete [] amounts;};
	virtual void count(const char* str);
	int getCount(char c) const
	{
		if(c>=first&&c<=last)
			return amounts[c-first];
		else
			return 0;
	};
};

Counter::Counter(char first,char last)
{
	this->first=first;
	this->last=last;
	amounts=new int[last-first+1];
}

void Counter::count(const char* str)
{
	for(int k=first; k<=last; k++)
	{
		int j=0;
		while(str[j]!='\0')
		{
			if(str[j]==k)
				amounts[k-first]++;
			j++;
		}
	}
}


The following code should print '3'

1
2
3
4
5
6
7
8
int main(int argc,char** argv)
{
	Counter charcounter;
	charcounter.count("hello");
	charcounter.count("world");
	cout << charcounter.getCount('l');
	return 0;
}


Now I want to make something like this possible:

1
2
3
4
5
6
7
int main(int argc,char** argv)
{
	Counter charcounter;
	charcounter << "hello" << "world";  // ?? charcounter.operator<<(operator<<("hello","world")) ??
	charcounter << cnt.getCount('l');
	return 0;
}


I do know a little about overloading operators, but I'm a little confused when it comes to expressions like 'charcounter << "hello" << "world";'

Does anybody know how I could implement something like this, this would really help me a lot.

Thanks
Last edited on
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
#include <iostream>
#include <vector>
#include <string>

struct char_counter
{
    char_counter( char first = 'a', char last = 'z' ) : first(first), last(last)
    { if( first <= last ) amounts.resize(last-first+1) ; }

    char_counter& operator << ( char c )
    { if( c >= first && c <= last ) ++amounts[c-first] ; return *this ; }

    char_counter& operator << ( const char* p )
    { for( ; *p != 0 ; ++p ) operator<< (*p) ; return *this ; }

    char_counter& operator << ( const std::string& str )
    { for( char c : str ) operator<< (c) ; return *this ; }

    std::vector<int> amounts ;
    const char first ;
    const char last ;
};

std::ostream& operator<< ( std::ostream& stm, const char_counter& counter )
{
    stm << "counts [" << counter.first << '-' << counter.last << "]: { " ;
    for( std::size_t i = 0 ; i < counter.amounts.size() ; ++i  )
    {
        int cnt = counter.amounts[i] ;
        if( cnt > 0 ) stm << char( i + counter.first ) << ':' << cnt << ' ' ;
    }
    return stm << '}' ;
}

int main()
{
    char_counter counter ;
    counter << 'a' << "abcde" << std::string("defg") << 'f' << "a?c?d?e?g?x" ;
    std::cout << counter << '\n' ;
}

http://ideone.com/arLx1d
I'm in two minds about this, but as it's on my mind:

While it's possible to overload C++ operators in all sorts of ways, by convention (or even rule) that you should preserve the natural semantics for overloaded operators (see "C++ Coding Standard", Sutter & Alexandresu, rule 26).

When it comes to operator<<, this convention means you should only really this operator in two situtations:

1. when you're shifting something left (following the lead of the built-in bitwise left-shift operator)

2. when your inserting into a sequential stream, like ostream.

Using operator<< to aggregate counts does not really fit into either of these categories, so your original count method is probably the better solution. It would even better if the method name made it clear that it also aggregates.

Andy
Last edited on
Topic archived. No new replies allowed.