Why does my compiler think this is an overloaded operator?

Started by
10 comments, last by theOcelot 15 years, 8 months ago
I have a critter class, defined here:
// Critter class declaration

#include <iostream>

using namespace std;

class Critter
{
public:
	string GetName() { return *m_pName; };
	virtual void Speak();

protected:
	string *m_pName;

	// Constructor & Destructor
	Critter( const string &name );
	~Critter();
};

Critter::Critter( const string &name )
{
	m_pName = new string( name );
}

Critter::~Critter()
{
	delete m_pName;
}

inline void Critter::Speak()
{
	cout << "Here." << endl;
}
I also have a 'farm' class that stores the critters and does things like call roll. In this function of 'farm'...
void Farm::RollCall()
{
	for( m_iter = m_vCritters.begin(); m_iter != m_vCritters.end(); m_iter++ )
		cout << m_iter->GetName() << " says:\t" << m_iter->Speak() << endl;

	return;
}
...an error pops up when I try to do this: m_iter->GetName() The error says that there's no overloaded operator-> for the 'critter' class. I'm not trying use an overloaded operator, I'm just trying to display the name of the critter. What's going wrong?
Advertisement
What is m_vCritters?
Why are you doing cout << m_iter->GetName() << " says:\t" << m_iter->Speak() << endl; when Critter::Speak() is a virtual void? Did you mean for Critter::Speak() to return a string?
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
0) Don't put using directives in header files. Doing so may subtly alter the way code compiles, and there is no way to undo it. Use fully qualified class names in header files instead.

1) Don't dynamically allocate members when its not necessary. The "name" member of the critter class should be a string instance, not a pointer. You are only making more work for yourself (and you aren't finished yet, you haven't followed the Rule of Three).

2) If you have any virtual functions, the destructor should be made virtual too. Failure to do so could result in the destructor not being called.

3) std::endl combines newline and a buffer flush. Use the character constant '\n' when you just want to put a newline. Its usually quicker to type too [smile]

4) Don't use inline like that. Compilers are free to ignore inline. The only time inline is necessary is when implementing a free function in a header file. Class functions can be made inline by writing the body inside the class.

5) I find it suspicious that the iterator is a member of the Farm. It should probably be a local variable.

6) Can we see the declaration of the Farm class?

From the above, the critter class could look like this:
#include <iostream>#include <string>class Critter{public:	string GetName() { return name; };	virtual void Speak() { std::cout << "Here.\n"; }protected:	std::string name;	Critter( const string &name ) : name(name) {}        virtual ~Critter() {}};
Since an iterator is not an actual pointer, you may have to explicitly do(*m_iter).GetName().
theOcelot is correct, you need to dereference your iterator to gain access to the object it actually contains.
No, if the vector contains Critters by value then the arrow operator works. If the vector contains pointers it will need an additional dereference, either (*it)->foo() or (**it).foo().
Except that it obviously isn't working. My guess is that this is not a std::vector, or anything else standard.

@OP: this isn't by any chance a custom container/iterator, is it?
It may not be working, but that doesn't mean that it's ok to spew nonsense while posting in For Beginners. Kindly think before posting misleading information.
Exactly what part of that was nonsense? No offense, I'm willing to be corrected, but I stated a fact, and qualified the rest as guessing.

This topic is closed to new replies.

Advertisement