Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Elwren

Overloading >> Operator

This topic is 5837 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

Hey, I''m trying to overload the << and >> operators so I can use them with a String class I have but I''m having difficulties. Every time I compile there is always an error on the >> overloaded function definition. The error it gives is "C2679: binary ''>>'' : no operator defined which takes a right-hand operand of type ''const char *'' (or there is no acceptable conversion)". I''m not sure what is the problem because this should work being that it came straight out of the book. Below is the code of the String class...Could someone shed some light on this problem? BTW: the error line is commented near the bottom. Sorry if the code is too long but I wasn''t sure if you needed the whole String class or not. Thanks in advance.
  
#include <iostream.h>
#include <string.h>

class String
{
public:
	//constructors

	String();
	String(const char *const);
	String(const String &);
	~String();

	//overloaded operators

	char & operator[] (unsigned short offset);
	char operator[] (unsigned short offset) const;
	String operator+(const String&);
	void operator+=(const String&);
	String & operator= (const String &);

    friend ostream& operator<<
       ( ostream&   _theStream,String& theString);
    friend istream& operator>>
       ( istream& _theStream,String& theString);


	// General Accessors

	unsigned short GetLen()const { return itsLen; }
	const char * GetString() const { return itsString; }

private:
	String(unsigned short); // private constructor

	char * itsString;
	unsigned short itsLen;
};

//default constructor creats string of 0 bytes

String::String()
{
	itsString = new char[1];
	itsString[0] = ''\0'';
	itsLen=0;
}

//private (helper) constructor, used only by

//class methods for creating a new string of

//required size.  Null filled

String::String(unsigned short len)
{
	itsString = new char[len+1];
	for (unsigned short i=0; i<=len; i++)
		itsString[i] = ''\0'';
	itsLen = len;
}

//Converts a character array to a String

String::String(const char * const cString)
{
	itsLen = strlen(cString);
	itsString = new char[itsLen+1];
	for (unsigned short i=0; i<itsLen; i++)
		itsString[i] = cString[i];
	itsString[itsLen] = ''\0'';
}

// copy constructor

String::String (const String & rhs)
{
	itsLen = rhs.GetLen();
	itsString = new char[itsLen+1];
	for (unsigned short i=0; i<itsLen; i++)
		itsString[i] = rhs[i];
	itsString[itsLen] = ''\0'';
}

// destructor, frees allocated memory

String::~String()
{
	delete [] itsString;
	itsLen = 0;
}

// operator equals, frees existing memory

// then copies string and size

String& String::operator=(const String & rhs)
{
	if (this==&rhs)
		return *this;
	delete [] itsString;
	itsLen=rhs.GetLen();
	itsString = new char[itsLen+1];
	for (unsigned short i =0; i<itsLen; i++)
		itsString[i] = rhs[i];
	itsString[itsLen] = ''\0'';
	return *this;
}

// nonconstant offset operator, returns

// referenece to character so it can be

// changed!

char & String::operator[] (unsigned short offset)
{
	if (offset > itsLen)
		return itsString[itsLen-1];
	else
		return itsString[offset];
}

// constant offset operator for use

// on const objects (see copy constructor!)

char String::operator[] (unsigned short offset) const
{
	if (offset > itsLen)
		return itsString[itsLen-1];
	else
		return itsString[offset];
}

// creates a new string by adding current

// string to rhs

String String::operator+(const String& rhs)
{
	unsigned short totalLen = itsLen + rhs.GetLen();
	String temp(totalLen);
	for (unsigned short i=0; i<itsLen; i++)
		temp[i] = itsString[i];
	for (unsigned short j=0; j<rhs.GetLen(); j++, i++)
		temp[i] = rhs[j];
	temp[totalLen] = ''\0'';
	return temp;
}

// changes current string, returns  nothing

void String::operator+=(const String& rhs)
{
	unsigned short rhsLen= rhs.GetLen();
	unsigned short totalLen = itsLen + rhsLen;
	String temp(totalLen);
	for (unsigned short i=0; i<itsLen; i++)
		temp[i] = itsString[i];
	for (unsigned short j=0; j<rhs.GetLen(); j++, i++)
		temp[i] = rhs[i-itsLen];
	temp[totalLen] = ''\0'';
	*this = temp;
}

//overloaded << and >> operators


ostream& operator<<( ostream& theStream,String& theString)
  {
      theStream << theString.GetString();
      return theStream;
  }
istream& operator>>( istream& theStream,String& theString)
  {
//the line underneath causes this error

      theStream >> theString.GetString();
      return theStream;
  }
  

Share this post


Link to post
Share on other sites
Advertisement
Your constructor for const char* looks kind of awry. Shouldn''t it just be String( const char* ); in the declaration? Also in the implementation for it, it should be const char* cString.

Share this post


Link to post
Share on other sites
It doesn''t work for the same reason this piece of code doesn''t:

  
#include <iostream>
int main()
{
// declares a CONST char * variable (getString returns a

// pointer to a member of the same type)

const char * blarg = new char[10];
// Q: how can cin place anything in a const variable?

// A: It can''t, cause its a constant.

std::cin >> blarg;
}


That sums it up. That book is wrong, or maybe you copied it incorrectly.

Share this post


Link to post
Share on other sites
here, this shud work, (off the top of my head, so may need a bit of debuging)

heres you prob,
the declaration of the operator should be outside of the public scope eg.

  
class string {
friend ostream& operator <<(...);
public:
...
}


also, the operator is a friend there for not a member ...
ie. ... operator<<(...) NOT ... string::operator<<(...)


  
ostream& operator <<(ostream& out, string_t str)
{
...
}



hope it helps =)

Share this post


Link to post
Share on other sites
quote:
Original post by silvermace
here, this shud work, (off the top of my head, so may need a bit of debuging)

heres you prob,
the declaration of the operator should be outside of the public scope eg.
class string {
friend ostream& operator <<(...);
public:
...
}



Sigh, this is unnecessary and unrelated to the problem at hand.

quote:

also, the operator is a friend there for not a member ...
ie. ... operatorNOT ... string::operator
ostream& operator <<(ostream& out, string_t str)
{
...
}
hope it helps =)


Just from reading the subject line (have you read it?), I believe he is having problems with overloading the stream extraction, NOT insertion, operator. Besides, what you just said here makes absolutely no sense since he made none of the mistakes you''re trying to make him aware of.



I will reiterate the solution again (so the original poster doesn''t get lost in the nonsense). Inside your overloaded >> operator, you are trying to extract from the input stream (theStream >>) into a const char * that''s returned by your theString.GetString() call. Look up your prototype (return type specifically) for GetString(). cin won''t accept this because it has no method that takes a const char * argument (even if it did, how would it place anything in that constant?).

Share this post


Link to post
Share on other sites
fallenang3l is right, dont listen to me =(
im an idiot, sorry to misguide you.

[edited by - silvermace on June 30, 2002 3:37:42 AM]

[edited by - silvermace on June 30, 2002 3:40:12 AM]

Share this post


Link to post
Share on other sites
Ah thanks guys...I took away the const from the "const char*" in the GetLine() function and it finally compiled without that error. Now I''m having a different problem but I believe it is still related to the >> operator. If I were to do the code below, it would crash the program after it tries to use the >> operator and put my input into a String. In the debug window it has a bunch of attempts to find a "matching symbollic symbol" in various .DLL''s...but it can''t find any. Is my >> overloaded operator defintion sufficient in what I''m trying to do? Thanks again

  
void main()
{

Character mainPlayer;
String myName;

cout << "What is your name?...";
cin >> myName;
mainPlayer.SetName(myName);

cout << "Your Name is....." << mainPlayer.GetName();


return;
}

Share this post


Link to post
Share on other sites
quote:
Original post by Elwren
If I were to do the code below, it would crash the program after it tries to use the >> operator and put my input into a String.

Buffer overflow? How big is the internal character buffer, and how many characters are you trying to read from the stream? Do you stop at whitespace?

Take a peek inside <string> and the various stream-related headers in the Standard C++ Library and see how they overcome this problem (operator >> should require validation to ensure that you have enough internal buffer space allocated, and a reallocation if you don''t). Additionally, it might be wise to allocate memory in regular sized chunks (or in logarithmically increasing proportion) to minimize reallocations, preferably in such a fashion that the user can control the granularity. This is part of what the STL/std::string offer by allowing custom allocators and providing a default one good enough for most situations.

Welcome to the world of software engineering.

Share this post


Link to post
Share on other sites
I''m not sure how it could be a buffer overflow...I''m only putting a small name in it like ''Dan''....Then again I''m a newbie programmer so who knows. I opened up the "string.h" and I have NO IDEA what was going on in there so I''m not sure how they overcame the >> problem. I''ve tested out my overloaded << operator with my String class and it worked fine and the >> overlaoded function is pretty much the same so I still guess it should work. Anywho, anyone with any ideas? Thanks

Share this post


Link to post
Share on other sites
quote:
Original post by Elwren
I''m not sure how it could be a buffer overflow...I''m only putting a small name in it like ''Dan''...

What''s the default size of the buffer allocated in the String constructor? One character. Still think the four-character "Dan" (with terminating null) can''t overflow it?

Besides, what''s the implementation for String::GetString?

quote:

I opened up the "string.h" and I have NO IDEA what was going on in there so I''m not sure how they overcame the >> problem.

Not <string.h> (which is from the Standard C Library and contains neither objects nor classes nor overloading), <string> (which is from the Standard C++ Library - specifically the STL - and contains the std::basic_string class and typedefs such as std::string for char type and appropriate traits).

quote:

I''ve tested out my overloaded << operator with my String class and it worked fine and the >> overlaoded function is pretty much the same so I still guess it should work.

Insertion and extraction are very different. Insertion delegates buffer management to the stream (the recipient) while extraction requires the String class do that as the roles are reversed.

Explain, step-by-step, what you think an extraction operator for a string should do (including all internal checks, validation and allocation).

Review your basic C++ concepts, too. Your use of const, for example, suggests that your grasp on the language is still gimpy.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!