This forum is in archive mode. You will not be able to post new content.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - forceez

Pages: [1]
1
C - C++ / Output operator overloading and templates
« on: October 19, 2014, 01:48:26 PM »
Cannot get the << overload working and cannot print the 'Account' instance using 'getter' method through Node. Not entirely sure what additional information to provide, please just ask for anything else I didn't clarify!
There is very obviously something wrong with my operator overloading, but I'm not sure what it is.

Account.cpp
Code: [Select]
#include "Account.h"
namespace myNamespace{
   // CONSTRUCTOR
   Account::Account(int initialValue)
   {
       acct_balance = initialValue;
   }
   //MUTATOR MEMBER FUNCTION
   void Account::deposit(int amount)
   {
       acct_balance += amount;
   }


   void Account::withdraw(int amount)
   {
       acct_balance -= amount;
   }


   void Account::setName(std::string newName)
   {
      name = newName;
   }
   //QUERY MEMBER FUNCTION
   int Account::balance() const
   {
       return acct_balance;
   }


   bool Account::has_funds() const
   {
      return (acct_balance > 0.0);
   }


   std::string Account::getName()
   {
      return name;
   }


   int& operator += (Account& a,const Account& b)
   {
      a.acct_balance += b.balance();
      return a.acct_balance;
   }


   std::ostream& operator << (std::ostream& out, const Account& a)
   {
      out << a.acct_balance;
   }
};



main.cpp
Code: [Select]

#include <iostream>
#include <string>
#include "Account.h"
#include "Node.h"




using namespace myNamespace;
using namespace std;


int main()
{
   Node<int>* intNode = new Node<int>(5);
   Node<std::string>* stringNode = new Node<std::string>("hello");
   Account* acc1 = new Account();
   Node<Account>* accountNode = new Node<Account>(*acc1);
   


   cout << "Initialised intNode with " << (intNode)->getData() << " ,\n";
   cout << "Initialised stringNode with "    << stringNode->getData() << " ,\n";
   cout << "Intiialised accountNode with $" << accountNode << "." << endl;
   return 0;
}


/*
Modify the Node class you produced in the last few weeks so that it becomes
a class template for a Node that can store a pointer to a generic type
instance. The constructor for your new Node returns a pointer to the newlycreated
Node instance, which has been created in the heap. Instantiate a
Node to store a pointer to an int; a pointer to a string; and a pointer to
an Account.
*/


Node.h
Code: [Select]

#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;


namespace myNamespace{
{
   template <class T>
   class Node
   {
   public:
      Node(T const& initData, Node<T>* const& initPrev = NULL, Node<T>* const& initNext = NULL);
      void setData(T newData);
      T getData();
      void setPrev(Node<T>* newPrev);
      Node<T>* getPrev();
      void setNext(Node<T>* newNext);
      Node<T>* getNext();


      friend std::ostream& operator << (std::ostream& out, const Node<T>& a);
   private:
      T data;
      Node<T> *next;
      Node<T> *prev;
   };
   #include "Node.template"
}
#endif


Node.template
Code: [Select]

template <class T>
Node<T>::Node(T const& initData, Node<T>* const& initPrev, Node<T>* const& initNext)
{
   data = initData;
   prev = initPrev;
   next = initNext;
}


template <class T>
void Node<T>::setData(T newData)
{
   data = newData;
}


template <class T>
T Node<T>::getData()
{
   return data;
}


template <class T>
void Node<T>::setPrev(Node<T>* newPrev)
{
   prev = newPrev;
}


template <class T>
Node<T>* Node<T>::getPrev()
{
   return prev;
}


template <class T>
void Node<T>::setNext(Node<T>* newNext)
{
   next = newNext;
}


template <class T>
Node<T>* Node<T>::getNext()
{
   return next;
}


template <class T>
std::ostream& operator << (std::ostream& out, const Node<T>& a)
{
   out << a->getData();
}



When I print it out using


Code: [Select]
cout << "Initialised intNode with " << (intNode) << " ,\n";
cout << "Initialised stringNode with "    << (stringNode) << " ,\n";
cout << "Intiialised accountNode with $" << (accountNode) << "." << endl;


The output is
Code: [Select]
Initialised intNode with 0x7f9251c03950 ,
Initialised stringNode with 0x7f9251c03970 ,
Intiialised accountNode with $0x7f9251c039c0.


When dereferencing, here is the error



Code: [Select]
Undefined symbols for architecture x86_64:
  "myNamespace::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, myNamespace::Node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&)", referenced from:
      _main in main.o
  "myNamespace::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, myNamespace::Node<myNamespace::Account> const&)", referenced from:
      _main in main.o
  "myNamespace::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, myNamespace::Node<int> const&)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [runfile] Error 1

EDIT: IT'S SOLVED, EVERYBODY! Turns out the error was because I'm stupid! xP

Pages: [1]


Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.