9 Replies - 1275 Views - Last Post: 14 February 2011 - 01:56 PM Rate Topic: -----

#1 Guest_Benjamin*


Reputation:

Overloading an operator << friend function

Posted 14 February 2011 - 12:55 PM

OK, so for a project my teacher told me that I needed to overload the << operator as a friend function. I have declared it in my header file, but I can't get it working.
friend ostream& Sequence::operator << (ostream & outData, Sequence &data);



std::ostream& operator<<(std::ostream &outData, Sequence &data)
{
	data.start();
	for(int i = 0; i < data.size(); i++)
	{
		outData << data.current();
		data.advance();
	}
	return outData;
}



Thanks in advance!

Is This A Good Question/Topic? 0

Replies To: Overloading an operator << friend function

#2 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:00 PM

Here is all of my code.

sequence.h
// FILE: sequence.h
// CLASS PROVIDED: sequence (part of the namespace main_savitch_3)
// There is no implementation file provided for this class since it is
// an exercise from Section 3.2 of "Data Structures and Other Objects Using C++"
//
// TYPEDEFS and MEMBER CONSTANTS for the sequence class:
//   typedef ____ value_type
//     sequence::value_type is the data type of the items in the sequence. It
//     may be any of the C++ built-in types (int, char, etc.), or a class with a
//     default constructor, an assignment operator, and a copy constructor.
//
//   typedef ____ size_type
//     sequence::size_type is the data type of any variable that keeps track of
//     how many items are in a sequence.
//
//   static const size_type CAPACITY = _____
//     sequence::CAPACITY is the maximum number of items that a sequence can hold.
//
// CONSTRUCTOR for the sequence class:
//   sequence( )
//     Postcondition: The sequence has been initialized as an empty sequence.
//
// MODIFICATION MEMBER FUNCTIONS for the sequence class:
//   void start( )
//     Postcondition: The first item on the sequence becomes the current item
//     (but if the sequence is empty, then there is no current item).
//
//   void advance( )
//     Precondition: is_item returns true.
//     Postcondition: If the current item was already the last item in the
//     sequence, then there is no longer any current item. Otherwise, the new
//     current item is the item immediately after the original current item.
//
//   void insert(const value_type& entry)
//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence
//     before the current item. If there was no current item, then the new entry 
//     has been inserted at the front of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
//
//   void attach(const value_type& entry)
//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence after
//     the current item. If there was no current item, then the new entry has 
//     been attached to the end of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
//
//   void remove_current( )
//     Precondition: is_item returns true.
//     Postcondition: The current item has been removed from the sequence, and the
//     item after this (if there is one) is now the new current item.
//
// CONSTANT MEMBER FUNCTIONS for the sequence class:
//   size_type size( ) const
//     Postcondition: The return value is the number of items in the sequence.
//
//   bool is_item( ) const
//     Postcondition: A true return value indicates that there is a valid
//     "current" item that may be retrieved by activating the current
//     member function (listed below). A false return value indicates that
//     there is no valid current item.
//
//   value_type current( ) const
//     Precondition: is_item( ) returns true.
//     Postcondition: The item returned is the current item in the sequence.
//
// VALUE SEMANTICS for the sequence class:
//    Assignments and the copy constructor may be used with sequence objects.

#ifndef MAIN_SAVITCH_SEQUENCE_H
#define MAIN_SAVITCH_SEQUENCE_H
#include <cstdlib>  // Provides size_t
#include <ostream>

namespace main_savitch_3
{
    class Sequence
    {
    public:
        // TYPEDEFS and MEMBER CONSTANTS
        typedef int value_type;
        typedef size_t size_type;
        static const size_type CAPACITY = 30;
        // CONSTRUCTOR
        Sequence();
		friend Sequence Sequence::operator + (Sequence, Sequence);
		friend ostream& Sequence::operator << (ostream & outData, Sequence &data);
//		friend istream Sequence::operator >> (istream&, const Sequence);
        // MODIFICATION MEMBER FUNCTIONS
        void start( );
        void advance( );
        void insert(const value_type& entry);
        void attach(const value_type& entry);
        void remove_current( );
        // CONSTANT MEMBER FUNCTIONS
        size_type size( );
        bool is_item( );
        value_type current( );
    private:
        value_type data[CAPACITY];
        size_type used;
        size_type current_index;
    };
}

#endif




sequence.cpp
#include <iostream>
#include <ostream>
#include "sequence.h"

using namespace std;

// TYPEDEFS and MEMBER CONSTANTS
typedef int value_type;
typedef std::size_t size_type;
static const size_type CAPACITY = 30;

value_type data[CAPACITY];
size_type used;
size_type current_index;

main_savitch_3::Sequence::Sequence()
{
	used = 0;
	current_index = 50;
}

main_savitch_3::Sequence main_savitch_3::operator + (main_savitch_3::Sequence first, main_savitch_3::Sequence second)
{
	main_savitch_3::Sequence answer;
	first.start();
	second.start();
	answer.start();
	int carry = 0;
	while((first.current() == 0 || first.current() == 1) && (second.current() == 0 || second.current() == 1))
	{
		if((first.current() + second.current() + carry) == 0)
		{
			answer.insert (0);
			carry = 0;
		}
		else
		{
			if((first.current() + second.current() + carry) == 1)
			{
				answer.insert (1);
				carry = 0;
			}
			else
			{
				if((first.current() + second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
				else
				{
					if((first.current() + second.current() + carry) == 3)
					{
						answer.insert(1);
						carry = 1;
					}
				}
			}
		}
		first.advance();
		second.advance();
	}

	while(first.current() == 0 || first.current() == 1)
	{
		if((first.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((first.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((first.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		first.advance();
	}
	while(second.current() == 0 || second.current() == 1)
	{
		if((second.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((second.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		second.advance();
	}
	if(carry == 1)
	{
		answer.insert(1);
	}
	return answer;
}

//ostream& main_savitch_3::operator<<(ostream &outData, main_savitch_3::Sequence &data)
//{
//	data.start();
//	for(int i = 0; i < data.size(); i++)
//	{
//		outData << data.current();
//		data.advance();
//	}
//	return outData;
//}

//     Postcondition: The first item on the sequence becomes the current item
//     (but if the sequence is empty, then there is no current item).
void main_savitch_3::Sequence::start()
{
	if(used > 0)
	{
		current_index = 0;
	}
	else
	{
		current_index = 50;
	}
}

//     Precondition: is_item returns true.
//     Postcondition: If the current item was already the last item in the
//     sequence, then there is no longer any current item. Otherwise, the new
//     current item is the item immediately after the original current item.
void main_savitch_3::Sequence::advance()
{
	if(current_index == (used - 1)  || current_index == 50)
	{
		current_index = 50;
	}
	else
	{
		current_index += 1;
	}
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence
//     before the current item. If there was no current item, then the new entry 
//     has been inserted at the front of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::insert(const value_type& entry)
{
	if(current_index == 50)
	{
		int usedCopy = used;
		while((usedCopy - 1) > 0)
		{
			data[usedCopy - 1] = data[usedCopy];
			usedCopy--;
		}
		data[0] = entry;
		current_index = 0;
	}
	else
	{
		int usedCopy = used;
		while((usedCopy - 1) > current_index)
		{
			data[usedCopy] = data[usedCopy - 1];
			usedCopy--;
		}
//		current_index++;
		if(used != 0)
		{
			data[current_index + 1] = data[current_index];
		}
		data[current_index] = entry;
	}
	used++;
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence after
//     the current item. If there was no current item, then the new entry has 
//     been attached to the end of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::attach(const value_type& entry)
{
	if(current_index == 50)
	{
		data[used] = entry;
		current_index = used - 1;
	}
	else
	{
		int copyUsed = used;
		while(current_index > copyUsed)
		{
			data[copyUsed] = data [copyUsed - 1];
			copyUsed--;
		}
		data[current_index + 1] = entry;
		current_index++;
	}
	used++;
}

//   void remove_current( )
//     Precondition: is_item returns true.
//     Postcondition: The current item has been removed from the sequence, and the
//     item after this (if there is one) is now the new current item.
void main_savitch_3::Sequence::remove_current( )
{
	data[current_index] = NULL;
	int copyUsed = used;
	int indexCopy = current_index;
	while((copyUsed - 1) > indexCopy)
	{
		data[indexCopy] = data[indexCopy + 1];
		indexCopy++;
	}
	used--;
}

//Postcondition: The return value is the number of items in the sequence.
size_type main_savitch_3::Sequence::size( )
{
	return used;
}

//Postcondition: A true return value indicates that there is a valid
//     "current" item that may be retrieved by activating the current
//     member function (listed below). A false return value indicates that
//     there is no valid current item.
bool main_savitch_3::Sequence::is_item( )
{
	return current();
}

//     Precondition: is_item( ) returns true.
//     Postcondition: The item returned is the current item in the sequence.
value_type main_savitch_3::Sequence::current( )
{
	return data[current_index];
}



binary.cpp
#include <iostream>
#include <fstream>
#include "sequence.h"

using namespace main_savitch_3;

int main()
{
	//Initialize input/output
	std::ofstream outData;
	std::ifstream inData;
	inData.open("input.txt");
	outData.open("output.txt");

	//Check that files are open and valid
	if(!inData.is_open() || !outData.is_open())
	{
		return 1;
	}

	//Data entry and processing until there is not more data to process
	while(!inData.eof())
	{
		//Initialize sequence files
		Sequence first;
		Sequence second;

		int input = inData.get();
		while(input == 48 || input == 49)
		{
			first.insert((input - 48));
			input = inData.get();
		}
		input = inData.get();
		while(input == 48 || input == 49)
		{
			second.insert((input - 48));
			input = inData.get();
		}
		first.start();
		for(int i = 0; i < first.size(); i++)
		{
			outData << first.current();
			first.advance();
		}
		outData << " ";
		second.start();
		for(int i = 0; i < second.size(); i++)
		{
			outData << second.current();
			second.advance();
		}
		outData << std::endl;

		outData << std::endl;
		Sequence answer = first + second;
		outData << answer;
		outData << std::endl;
		outData << std::endl;
	}
	
	return 0;
}

std::ostream& operator<<(std::ostream &outData, Sequence &data)
{
	data.start();
	for(int i = 0; i < data.size(); i++)
	{
		outData << data.current();
		data.advance();
	}
	return outData;
}


Was This Post Helpful? 0

#3 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6048
  • View blog
  • Posts: 23,473
  • Joined: 23-August 08

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:03 PM

Sigh...

Quote

I can't get it working


WHY???? What is the problem???

Read this, please.
Was This Post Helpful? 1
  • +
  • -

#4 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:09 PM

Sorry, it is currently not compiling for me and I can't figure out why. The first few errors are:
1>c:\users\ben\documents\visual studio 2010\projects\binary\binary\sequence.h(87): error C2143: syntax error : missing ';' before '&'
1>c:\users\ben\documents\visual studio 2010\projects\binary\binary\sequence.h(87): error C2433: 'main_savitch_3::ostream' : 'friend' not permitted on data declarations
1>c:\users\ben\documents\visual studio 2010\projects\binary\binary\sequence.h(87): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

And on line 121 in sequence.cpp (which is commented right now) I get an error on operator saying: declaration is incompatible.

Thanks.
Was This Post Helpful? 0

#5 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6048
  • View blog
  • Posts: 23,473
  • Joined: 23-August 08

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:13 PM

There, wasn't that easy?

friend ostream& Sequence::operator << (ostream & outData, Sequence &data);


This is going to be a friend function, not a member function; therefore it should not have the Sequence:: scope resolution operator attached to it.
Was This Post Helpful? 0
  • +
  • -

#6 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:21 PM

OK, and where do I implement the function? It's supposed to be in my sequence.cpp file right? I changed it, but I am still not able to compile due to something in the sequence.h file around line 87. I'm getting a syntax error and an error saying that friend functions are not permitted on data declarations.

Thanks!
Was This Post Helpful? 0

#7 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:32 PM

I just changed in sequence.h
friend std::ostream& operator << (std::ostream& outData, Sequence& data);


This works better and I get almost no errors except for an unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl main_savitch_3::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class main_savitch_3::Sequence &)" (??6main_savitch_3@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@AAVSequence@0@@Z) referenced in function _main

Any idea what that means? I also, uncommented the function's implementation in the sequence.cpp and changed it to:
std::ostream& operator<<(std::ostream& outData, main_savitch_3::Sequence& data)



I also then deleted it from the bottom of my binary.cpp file.

Thanks.
Was This Post Helpful? 0

#8 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:42 PM

can you re-post what you have now?

can you re-post what you have now?
Was This Post Helpful? 0
  • +
  • -

#9 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:46 PM

Alright. I make a few additional changes but can't seem to access the private class variables with the friend function.

sequence.h
// FILE: sequence.h
// CLASS PROVIDED: sequence (part of the namespace main_savitch_3)
// There is no implementation file provided for this class since it is
// an exercise from Section 3.2 of "Data Structures and Other Objects Using C++"
//
// TYPEDEFS and MEMBER CONSTANTS for the sequence class:
//   typedef ____ value_type
//     sequence::value_type is the data type of the items in the sequence. It
//     may be any of the C++ built-in types (int, char, etc.), or a class with a
//     default constructor, an assignment operator, and a copy constructor.
//
//   typedef ____ size_type
//     sequence::size_type is the data type of any variable that keeps track of
//     how many items are in a sequence.
//
//   static const size_type CAPACITY = _____
//     sequence::CAPACITY is the maximum number of items that a sequence can hold.
//
// CONSTRUCTOR for the sequence class:
//   sequence( )
//     Postcondition: The sequence has been initialized as an empty sequence.
//
// MODIFICATION MEMBER FUNCTIONS for the sequence class:
//   void start( )
//     Postcondition: The first item on the sequence becomes the current item
//     (but if the sequence is empty, then there is no current item).
//
//   void advance( )
//     Precondition: is_item returns true.
//     Postcondition: If the current item was already the last item in the
//     sequence, then there is no longer any current item. Otherwise, the new
//     current item is the item immediately after the original current item.
//
//   void insert(const value_type& entry)
//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence
//     before the current item. If there was no current item, then the new entry 
//     has been inserted at the front of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
//
//   void attach(const value_type& entry)
//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence after
//     the current item. If there was no current item, then the new entry has 
//     been attached to the end of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
//
//   void remove_current( )
//     Precondition: is_item returns true.
//     Postcondition: The current item has been removed from the sequence, and the
//     item after this (if there is one) is now the new current item.
//
// CONSTANT MEMBER FUNCTIONS for the sequence class:
//   size_type size( ) const
//     Postcondition: The return value is the number of items in the sequence.
//
//   bool is_item( ) const
//     Postcondition: A true return value indicates that there is a valid
//     "current" item that may be retrieved by activating the current
//     member function (listed below). A false return value indicates that
//     there is no valid current item.
//
//   value_type current( ) const
//     Precondition: is_item( ) returns true.
//     Postcondition: The item returned is the current item in the sequence.
//
// VALUE SEMANTICS for the sequence class:
//    Assignments and the copy constructor may be used with sequence objects.

#ifndef MAIN_SAVITCH_SEQUENCE_H
#define MAIN_SAVITCH_SEQUENCE_H
#include <cstdlib>  // Provides size_t
#include <ostream>

namespace main_savitch_3
{
    class Sequence
    {
    public:
        // TYPEDEFS and MEMBER CONSTANTS
        typedef int value_type;
        typedef size_t size_type;
        static const size_type CAPACITY = 30;
        // CONSTRUCTOR
        Sequence();
		friend Sequence Sequence::operator + (Sequence, Sequence);
		friend std::ostream& operator << (std::ostream& outData, Sequence & inData);
//		friend istream Sequence::operator >> (istream&, const Sequence);
        // MODIFICATION MEMBER FUNCTIONS
        void start( );
        void advance( );
        void insert(const value_type& entry);
        void attach(const value_type& entry);
        void remove_current( );
        // CONSTANT MEMBER FUNCTIONS
        size_type size( );
        bool is_item( );
        value_type current( );
    private:
        value_type data[CAPACITY];
        size_type used;
        size_type current_index;
    };
}

#endif





sequence.cpp

#include <iostream>
#include <ostream>
#include "sequence.h"

using namespace std;

// TYPEDEFS and MEMBER CONSTANTS
typedef int value_type;
typedef std::size_t size_type;
static const size_type CAPACITY = 30;

value_type data[CAPACITY];
size_type used;
size_type current_index;

main_savitch_3::Sequence::Sequence()
{
	used = 0;
	current_index = 50;
}

main_savitch_3::Sequence main_savitch_3::operator + (main_savitch_3::Sequence first, main_savitch_3::Sequence second)
{
	main_savitch_3::Sequence answer;
	first.start();
	second.start();
	answer.start();
	int carry = 0;
	while((first.current() == 0 || first.current() == 1) && (second.current() == 0 || second.current() == 1))
	{
		if((first.current() + second.current() + carry) == 0)
		{
			answer.insert (0);
			carry = 0;
		}
		else
		{
			if((first.current() + second.current() + carry) == 1)
			{
				answer.insert (1);
				carry = 0;
			}
			else
			{
				if((first.current() + second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
				else
				{
					if((first.current() + second.current() + carry) == 3)
					{
						answer.insert(1);
						carry = 1;
					}
				}
			}
		}
		first.advance();
		second.advance();
	}

	while(first.current() == 0 || first.current() == 1)
	{
		if((first.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((first.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((first.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		first.advance();
	}
	while(second.current() == 0 || second.current() == 1)
	{
		if((second.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((second.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		second.advance();
	}
	if(carry == 1)
	{
		answer.insert(1);
	}
	return answer;
}

std::ostream& operator<<(std::ostream& outData, main_savitch_3::Sequence & inData)
{
//	data.start();
//	for(int i = 0; i < data.size(); i++)
//	{
//		outData << data.current();
//		data.advance();
//	}
	for(int i = 0; i < inData.size(); i++)
	{
		outData << inData.data[i];
	}

	return outData;
}

//     Postcondition: The first item on the sequence becomes the current item
//     (but if the sequence is empty, then there is no current item).
void main_savitch_3::Sequence::start()
{
	if(used > 0)
	{
		current_index = 0;
	}
	else
	{
		current_index = 50;
	}
}

//     Precondition: is_item returns true.
//     Postcondition: If the current item was already the last item in the
//     sequence, then there is no longer any current item. Otherwise, the new
//     current item is the item immediately after the original current item.
void main_savitch_3::Sequence::advance()
{
	if(current_index == (used - 1)  || current_index == 50)
	{
		current_index = 50;
	}
	else
	{
		current_index += 1;
	}
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence
//     before the current item. If there was no current item, then the new entry 
//     has been inserted at the front of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::insert(const value_type& entry)
{
	if(current_index == 50)
	{
		int usedCopy = used;
		while((usedCopy - 1) > 0)
		{
			data[usedCopy - 1] = data[usedCopy];
			usedCopy--;
		}
		data[0] = entry;
		current_index = 0;
	}
	else
	{
		int usedCopy = used;
		while((usedCopy - 1) > current_index)
		{
			data[usedCopy] = data[usedCopy - 1];
			usedCopy--;
		}
//		current_index++;
		if(used != 0)
		{
			data[current_index + 1] = data[current_index];
		}
		data[current_index] = entry;
	}
	used++;
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence after
//     the current item. If there was no current item, then the new entry has 
//     been attached to the end of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::attach(const value_type& entry)
{
	if(current_index == 50)
	{
		data[used] = entry;
		current_index = used - 1;
	}
	else
	{
		int copyUsed = used;
		while(current_index > copyUsed)
		{
			data[copyUsed] = data [copyUsed - 1];
			copyUsed--;
		}
		data[current_index + 1] = entry;
		current_index++;
	}
	used++;
}

//   void remove_current( )
//     Precondition: is_item returns true.
//     Postcondition: The current item has been removed from the sequence, and the
//     item after this (if there is one) is now the new current item.
void main_savitch_3::Sequence::remove_current( )
{
	data[current_index] = NULL;
	int copyUsed = used;
	int indexCopy = current_index;
	while((copyUsed - 1) > indexCopy)
	{
		data[indexCopy] = data[indexCopy + 1];
		indexCopy++;
	}
	used--;
}

//Postcondition: The return value is the number of items in the sequence.
size_type main_savitch_3::Sequence::size( )
{
	return used;
}

//Postcondition: A true return value indicates that there is a valid
//     "current" item that may be retrieved by activating the current
//     member function (listed below). A false return value indicates that
//     there is no valid current item.
bool main_savitch_3::Sequence::is_item( )
{
	return current();
}

//     Precondition: is_item( ) returns true.
//     Postcondition: The item returned is the current item in the sequence.
value_type main_savitch_3::Sequence::current( )
{
	return data[current_index];
}





binary.cpp
#include <iostream>
#include <fstream>
#include "sequence.h"

using namespace main_savitch_3;

int main()
{
	//Initialize input/output
	std::ofstream outData;
	std::ifstream inData;
	inData.open("input.txt");
	outData.open("output.txt");

	//Check that files are open and valid
	if(!inData.is_open() || !outData.is_open())
	{
		return 1;
	}

	//Data entry and processing until there is not more data to process
	while(!inData.eof())
	{
		//Initialize sequence files
		Sequence first;
		Sequence second;

		int input = inData.get();
		while(input == 48 || input == 49)
		{
			first.insert((input - 48));
			input = inData.get();
		}
		input = inData.get();
		while(input == 48 || input == 49)
		{
			second.insert((input - 48));
			input = inData.get();
		}
		first.start();
		for(int i = 0; i < first.size(); i++)
		{
			outData << first.current();
			first.advance();
		}
		outData << " ";
		second.start();
		for(int i = 0; i < second.size(); i++)
		{
			outData << second.current();
			second.advance();
		}
		outData << std::endl;

		outData << std::endl;
		Sequence answer = first + second;
		outData << answer;
		outData << std::endl;
		outData << std::endl;
	}
	
	return 0;
}


Was This Post Helpful? 0

#10 Guest_Benjamin*


Reputation:

Re: Overloading an operator << friend function

Posted 14 February 2011 - 01:56 PM

OK, the access to private variables is working now. However, I'm getting a unresolved external symbol now...


1>binary.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl main_savitch_3::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class main_savitch_3::Sequence &)" (??6main_savitch_3@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@AAVSequence@0@@Z) referenced in function _main
1>C:\Users\Ben\Documents\Visual Studio 2010\Projects\Binary\Debug\Binary.exe : fatal error LNK1120: 1 unresolved externals

Updated sequence.cpp file:
#include <iostream>
#include <ostream>
#include "sequence.h"

using namespace std;

// TYPEDEFS and MEMBER CONSTANTS
typedef int value_type;
typedef std::size_t size_type;
static const size_type CAPACITY = 30;

value_type data[CAPACITY];
size_type used;
size_type current_index;

main_savitch_3::Sequence::Sequence()
{
	used = 0;
	current_index = 50;
}

main_savitch_3::Sequence main_savitch_3::operator + (main_savitch_3::Sequence first, main_savitch_3::Sequence second)
{
	main_savitch_3::Sequence answer;
	first.start();
	second.start();
	answer.start();
	int carry = 0;
	while((first.current() == 0 || first.current() == 1) && (second.current() == 0 || second.current() == 1))
	{
		if((first.current() + second.current() + carry) == 0)
		{
			answer.insert (0);
			carry = 0;
		}
		else
		{
			if((first.current() + second.current() + carry) == 1)
			{
				answer.insert (1);
				carry = 0;
			}
			else
			{
				if((first.current() + second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
				else
				{
					if((first.current() + second.current() + carry) == 3)
					{
						answer.insert(1);
						carry = 1;
					}
				}
			}
		}
		first.advance();
		second.advance();
	}

	while(first.current() == 0 || first.current() == 1)
	{
		if((first.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((first.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((first.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		first.advance();
	}
	while(second.current() == 0 || second.current() == 1)
	{
		if((second.current() + carry) == 0)
		{
			answer.insert(0);
			carry = 0;
		}
		else
		{
			if((second.current() + carry) == 1)
			{
				answer.insert(1);
				carry = 0;
			}
			else
			{
				if((second.current() + carry) == 2)
				{
					answer.insert(0);
					carry = 1;
				}
			}
		}
		second.advance();
	}
	if(carry == 1)
	{
		answer.insert(1);
	}
	return answer;
}

std::ostream& operator<<(std::ostream& outData, main_savitch_3::Sequence & inData)
{
//	data.start();
//	for(int i = 0; i < data.size(); i++)
//	{
//		outData << data.current();
//		data.advance();
//	}
	int dataCopy[CAPACITY];
	for(int i = 0; i < inData.size(); i++)
	{
		dataCopy[i] = data[i];
		outData << data[i];
	}
	return outData;
}

//     Postcondition: The first item on the sequence becomes the current item
//     (but if the sequence is empty, then there is no current item).
void main_savitch_3::Sequence::start()
{
	if(used > 0)
	{
		current_index = 0;
	}
	else
	{
		current_index = 50;
	}
}

//     Precondition: is_item returns true.
//     Postcondition: If the current item was already the last item in the
//     sequence, then there is no longer any current item. Otherwise, the new
//     current item is the item immediately after the original current item.
void main_savitch_3::Sequence::advance()
{
	if(current_index == (used - 1)  || current_index == 50)
	{
		current_index = 50;
	}
	else
	{
		current_index += 1;
	}
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence
//     before the current item. If there was no current item, then the new entry 
//     has been inserted at the front of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::insert(const value_type& entry)
{
	if(current_index == 50)
	{
		int usedCopy = used;
		while((usedCopy - 1) > 0)
		{
			data[usedCopy - 1] = data[usedCopy];
			usedCopy--;
		}
		data[0] = entry;
		current_index = 0;
	}
	else
	{
		int usedCopy = used;
		while((usedCopy - 1) > current_index)
		{
			data[usedCopy] = data[usedCopy - 1];
			usedCopy--;
		}
//		current_index++;
		if(used != 0)
		{
			data[current_index + 1] = data[current_index];
		}
		data[current_index] = entry;
	}
	used++;
}

//     Precondition: size( ) < CAPACITY.
//     Postcondition: A new copy of entry has been inserted in the sequence after
//     the current item. If there was no current item, then the new entry has 
//     been attached to the end of the sequence. In either case, the newly
//     inserted item is now the current item of the sequence.
void main_savitch_3::Sequence::attach(const value_type& entry)
{
	if(current_index == 50)
	{
		data[used] = entry;
		current_index = used - 1;
	}
	else
	{
		int copyUsed = used;
		while(current_index > copyUsed)
		{
			data[copyUsed] = data [copyUsed - 1];
			copyUsed--;
		}
		data[current_index + 1] = entry;
		current_index++;
	}
	used++;
}

//   void remove_current( )
//     Precondition: is_item returns true.
//     Postcondition: The current item has been removed from the sequence, and the
//     item after this (if there is one) is now the new current item.
void main_savitch_3::Sequence::remove_current( )
{
	data[current_index] = NULL;
	int copyUsed = used;
	int indexCopy = current_index;
	while((copyUsed - 1) > indexCopy)
	{
		data[indexCopy] = data[indexCopy + 1];
		indexCopy++;
	}
	used--;
}

//Postcondition: The return value is the number of items in the sequence.
size_type main_savitch_3::Sequence::size( )
{
	return used;
}

//Postcondition: A true return value indicates that there is a valid
//     "current" item that may be retrieved by activating the current
//     member function (listed below). A false return value indicates that
//     there is no valid current item.
bool main_savitch_3::Sequence::is_item( )
{
	return current();
}

//     Precondition: is_item( ) returns true.
//     Postcondition: The item returned is the current item in the sequence.
value_type main_savitch_3::Sequence::current( )
{
	return data[current_index];
}




Was This Post Helpful? 0

Page 1 of 1