Sign in to follow this  

Why does my compiler think this is an overloaded operator?

This topic is 3437 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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() {}
};


Share this post


Link to post
Share on other sites
Since an iterator is not an actual pointer, you may have to explicitly do(*m_iter).GetName().

Share this post


Link to post
Share on other sites
theOcelot is correct, you need to dereference your iterator to gain access to the object it actually contains.

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Nonsense:
Quote:
Since an iterator is not an actual pointer, you may have to explicitly do(*m_iter).GetName().

In C++, for an iterator i, i->name is always the same as (*i).name. See section 24.1.1 in the C++ Standard.

Share this post


Link to post
Share on other sites
Oh that, I thought you meant my last post. Like I said, it may not be standards-compliant. Thanks for the correction, though.

Share this post


Link to post
Share on other sites

This topic is 3437 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this