Errors implementing class functions "no match for operator"

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

44 Replies - 1309 Views - Last Post: 25 September 2013 - 10:54 PM Rate Topic: -----

#31 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 07:23 PM

Hi, the other number/list could be called other:


Natural::Natural (const Natural& other)
{
  leadingDigit = trailingDigit = new DigitList(other.leadingDigit->data, 0, 0);
}



With the for loop you could have used the nDigits in the other object to compare with, but you will need to use pointers anyway.

DigitList* d;
// initialize with first item 
// from other number/list
leadingDigit = trailingDigit = new DigitList(i.leadingDigit->data, 0, 0);

// point to second item or null
d = i.leadingDigit->next;
while (d !=NULL)
{
  addTrailingDigit(/* digit from other list */);
  // move pointer to next digit of other list
}
nDigits = nDigits; 




Linked list
Was This Post Helpful? 1
  • +
  • -

#32 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 07:36 PM

Sorry, I don't quite get it. If I add another Natural(const Natural&) it gives me
natural2.cpp:15: error: redefinition of `Natural::Natural(const Natural&)'
Was This Post Helpful? 0
  • +
  • -

#33 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 07:44 PM

Yep, I'm not telling you to create another function. I'm saying that the parameter could be named something else (I'm not telling you to actually change it). I was trying to point out that you are extracting data from an other list, which is currently part of the object named i.
Was This Post Helpful? 1
  • +
  • -

#34 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 07:50 PM

I see. I think I'm getting closer.

  DigitList* d;
  DigitList* end;
  leadingDigit = trailingDigit = new DigitList(i.leadingDigit->data, 0, 0);
  end = i.leadingDigit;
  d = i.leadingDigit->next;
  while (d != NULL)
  {
	addTrailingDigit(end);
  }
  nDigits = nDigits;



I believe the only problem is end is a pointer not an int, so I need to get the int that i.leadingDigit is pointing to?
Was This Post Helpful? 0
  • +
  • -

#35 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 08:06 PM

DigitList* d;
  int end;
  leadingDigit = trailingDigit = new DigitList(i.leadingDigit->data, 0, 0);
  end = i.nDigits;
  d = i.leadingDigit->next;
  while (d != NULL)
  {
	addTrailingDigit(end);
  }
  nDigits = nDigits;


That's about all I could come up with sadly, I am just missing something here. I dislike this style of editing pre-provided code, but what are you going to do? I appreciate all your help, I have to turn in what I have in about 15 minutes. I have learned a lot though, frankly more than my chapter talked about. Thank you for all your help everyone.
Was This Post Helpful? 0
  • +
  • -

#36 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 08:14 PM

Hi, pointers take getting used to, this is what I came up :

DigitList* d;
// initialize list with first item 
// from other number/list
leadingDigit = trailingDigit = new DigitList(i.leadingDigit->data, 0, 0);

// point to second item (or null)
d = i.leadingDigit->next;
while (d !=NULL)
{
  // add digit from other list 
  addTrailingDigit(d->data);
  // next digit
  d = d->next;
}

// update number of digits
nDigits = i.nDigits; 



not sure if it works.

This post has been edited by #define: 25 September 2013 - 08:17 PM

Was This Post Helpful? 1
  • +
  • -

#37 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 08:20 PM

I see. Yea, pointers are very abstract for me at the moment. It still won't run, though the debugging isn't helping. I'm still getting
0x610ff7fc in cygwin1!__getreent ()
from ~home/Cygwin/bin/cygwin1.dll
(gdb) backtrace
#0 0x610ff7fc in cygwin1!__getreent ()
~home/Cygwin/bin/cygwin1.dll
#1 0x00000000 in ?? ()

natural.h
#ifndef NATURAL_H
#define NATURAL_H

#include <iostream>
#include <utility>
#include <cmath>

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

class Natural
{
public:
  Natural();
  //   Natural k;
  //post:  k == 0

  Natural (unsigned i);
  //   Natural k = i;
  //post:  k == i

  Natural (const Natural&);
  ~Natural();
  Natural& operator= (const Natural&);

  Natural& operator+= (const Natural&);
    
  Natural& operator++ ();
  Natural operator++ (int);
  Natural& operator-- ();
  Natural operator-- (int);

private:

  // Implemented as a linked list of digits, each digit should
  // be a number between 0 and 9, inclusive.
  struct DigitList {
    int data;
    DigitList* prev;
    DigitList* next;

    DigitList (unsigned d, DigitList* prv = 0, DigitList* nxt = 0)
      : data(d), prev(prv), next(nxt)
      {}
  };
  unsigned nDigits;
  DigitList* leadingDigit;
  DigitList* trailingDigit;
  

  void clear();
  // Empty the list

  void normalize();
  // Between operations (though not necessarily during the implementation
  // of an operation), all Natural numbers should be in "normal form" 
  //   - each digit should be between 0 and 9, inclusive
  //   - the leading digit should be non-zero, unless the number itself is
  //     zero, in which case it will have a single zero digit
  // This function scans the number, correcting any deviations from
  // normal form.

  // Internal operations for list manipulation
  void addLeadingZero();
  // adds a 0 digit to the front of the number

  void addTrailingDigit(int);
  //adds a digit to the end of the number
  
  void timesTen();
  // adds a 0 digit to the end of the number, effectively multiplying it by 10

  void divTen();
  // removes the trailing digit of a number, effectively dividing it by 10

  friend Natural operator+ (const Natural& i, const Natural& j);
  friend Natural operator- (const Natural& i, const Natural& j);
  friend Natural operator* (const Natural& i, const Natural& j);
  friend Natural operator/ (const Natural& i, const Natural& j);
   
  friend std::ostream&  operator<< (std::ostream& out, const Natural& k);


  // Utility functions

  void multiplyByDigit (unsigned i);
  //pre: 0 <= i < 10
  //   Natural k = k0;  k.multiplyBy(i);
  //post: k == k0 * i

  void divideBy2 ();  
  //   Natural k = k0;  j = k.divideBy2();
  //post: k0 == 2*k  || k0 = 2*k + 1

  void subtract1 ();
  //   Natural k = k0; k.subtract1();
  //Post:  k0 == k + 1

};


Natural operator+ (const Natural& i, const Natural& j);
Natural operator- (const Natural& i, const Natural& j);
Natural operator* (const Natural& i, const Natural& j);
Natural operator/ (const Natural& i, const Natural& j);
bool operator== (const Natural& i, const Natural& j);
bool operator< (const Natural& i, const Natural& j);

using namespace std::rel_ops;

std::ostream&  operator<< (std::ostream& out, const Natural& k);


#endif





natural1.cpp
#include "natural.h"

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

Natural::Natural()
//   Natural k;
//post:  k == 0
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(0);
}

Natural::Natural (unsigned i)
//   Natural k = i;
//post:  k == i
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(i);
  normalize();
}



Natural& Natural::operator++ ()
{
  ++(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator++ (int)
{
  Natural original = *this;
  ++(trailingDigit->data);
  normalize();
  return original;
}

Natural& Natural::operator-- ()
{
  --(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator-- (int)
{
  Natural original = *this;
  --(trailingDigit->data);
  normalize();
  return original;
}



void Natural::normalize()
// Between operations (though not necessarily during the implementation
// of an operation), all Natural numbers should be in "normal form" 
//   - each digit should be between 0 and 9, inclusive
//   - the leading digit should be non-zero, unless the number itself is
//     zero, in which case it will have a single zero digit
// This function scans the number, correcting any deviations from
// normal form.
{
  DigitList* d = trailingDigit;
  int carry = 0;
  while (d != 0)
    {
      d->data += carry;
      carry = 0;
      if (d->data >= 10)
	{
	  carry = d->data / 10;
	  d->data = d->data % 10;
	}
      else if (d->data < 0)
	{
	  carry = 1 + (-(d->data+1)) / 10;
	  d->data = (carry * 10 + d->data);
	  carry = -carry;
	}
      d = d->prev;
    }
  while (carry > 0)
    {
      addLeadingZero();
      leadingDigit->data = carry % 10;
      carry = carry / 10;
    }
  d = leadingDigit;
  while (d != 0 && d->data == 0 && d != trailingDigit) 
    {
      leadingDigit = d->next;
      delete d;
      leadingDigit->prev = 0;
      --nDigits;
      d = leadingDigit;
    }
  if (carry < 0)
    {
      clear();
      nDigits = 1;
      leadingDigit = trailingDigit = new DigitList(0);
    }
}


// Internal operations for list manipulation

void Natural::clear()
{
  for (DigitList* d = leadingDigit; d != NULL;)
      {
	DigitList* nxt = d->next;
	delete d;
	d = nxt;
      }
  nDigits = 0;
}



void Natural::addLeadingZero()
// adds a 0 digit to the front of the number
{
  DigitList* d = new DigitList(0, 0, leadingDigit);
  leadingDigit->prev = d;
  leadingDigit = d;
  ++nDigits;
}



void Natural::timesTen()
// adds a 0 digit to the end of the number, effectively 
//  multiplying it by 10
{
  DigitList* d = new DigitList(0, trailingDigit, 0);
  trailingDigit->next = d;
  trailingDigit = d;
  ++nDigits;
}


void Natural::divTen()
// Removes the trailing digit of the number, effectively 
//  dividing it by 10
{
  DigitList* d = trailingDigit;
  trailingDigit = d->prev;
  if (trailingDigit == 0)
    leadingDigit = 0;
  else
    trailingDigit->next = 0;
  delete d;
  --nDigits;
}


Natural operator+ (const Natural& i, const Natural& j)
{
  Natural k = i;
  k += j;
  return k;
}


Natural operator* (const Natural& i, const Natural& j)
{
  Natural sum;
  Natural ii = i;
  for (Natural::DigitList* d = j.trailingDigit; d != 0; d = d->prev)
    {
      Natural m = ii;
      m.multiplyByDigit(d->data);
      sum += m;
      ii.timesTen();
    }
  return sum;
}


Natural operator/ (const Natural& i, const Natural& j)
{
  Natural quotient;
  Natural divisor = j;
  Natural remainder = i;

  int nShifts = 0;

  while (divisor.nDigits < remainder.nDigits)
    {
      divisor.timesTen();
      ++nShifts;
    }

  for (int i = 0; i <= nShifts; ++i)
    {
      int digit = 0;
      while (divisor <= remainder)
	{
	  remainder = remainder - divisor;
	  ++digit;
	}
      if (i > 0)
	quotient.timesTen();
      quotient.trailingDigit->data = digit;
      divisor.divTen();
    }
  quotient.normalize();
  return quotient;
}
  


ostream&  operator<< (ostream& out, const Natural& k)
{
  for (Natural::DigitList* d = k.leadingDigit; d != 0; d = d->next)
    out << d->data;
  return out;
}


// Utility functions

void Natural::multiplyByDigit (unsigned i)
//pre: 0 <= i < 10
//   Natural k = k0;  k.multiplyBy(i);
//post: k == k0 * i
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data *= i;
  normalize();
}


void Natural::divideBy2 ()
//   Natural k = k0;  j = k.divideBy2();
//post: k0 == 2*k  || k0 = 2*k + 1
{
  int carry = 0;
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    {
      int k = 10 * carry + d->data;
      d->data = k / 2;
      carry = k % 2;
    }
  normalize();
}



natural2.cpp
#include "natural.h"


using namespace std;


// Insert your own function bodies in this file

Natural::Natural (const Natural& i)
{
  DigitList* d;
  leadingDigit = trailingDigit = new DigitList(i.leadingDigit->data, 0, 0);
  d = i.leadingDigit->next;
  while (d != NULL)
  {
	addTrailingDigit(d->data);
	d = d->next;
  }
  nDigits = i.nDigits;

}

Natural::~Natural()
{
    clear();
}

Natural& Natural::operator= (const Natural& i)
{
  if (this != &i)
      {
          clear();
          nDigits = i.nDigits;
          for (unsigned j = 0; j <= nDigits; ++j)
            leadingDigit[j] = i.leadingDigit[j];
      }
    return *this;
}

Natural& Natural::operator+= (const Natural& i)
{
  *this += i;
  return *this;
}

void Natural::addTrailingDigit(int digit)
{
  DigitList* d = new DigitList(digit, trailingDigit,0);
  trailingDigit->next = d;
  trailingDigit = d;
  ++nDigits;
}

void Natural::subtract1 ()
//   Natural k = k0; k.subtract1();
//Post:  k0 == k + 1
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data -= 1;
  normalize();
}

Natural operator- (const Natural& i, const Natural& j)
{
  Natural k = i;
  k = k - j;
  return k;
}

bool operator== (const Natural& i, const Natural& j)
{
  return i == j;
}

bool operator< (const Natural& i, const Natural& j)
{
  if (i-j<0)
  {
    return (i<j);
   }
   else
   {
   return !(i<j);
   }
   
}




odds.cpp

#include <iostream>
#include "natural.h"


using namespace std;



Natural factorial (const Natural& j)
{
  Natural k = 1;
  for (Natural i = 2; i <= j; ++i)
    {
      k = k * i;
    }
  return k;
}


int main (int argc, char** argv) 
{
  unsigned k, n;
  cout << "What is the largest number in the lottery? " << flush;
  cin >> n;
  cout << "\nHow many numbers in each drawing? " << flush;
  cin >> k;
  cout << "\n";

  // Additional output for debugging purposes
  //  (and to help in providing partial credit when grading)
  //  is activated by running the program with a -debug flag:
  //    lottery.exe -debug
  string debugFlag ((argc > 1) ? argv[1] : "");
  if (debugFlag == "-debug")
    {
      Natural x = n;
      
      // try doubling x 32 times to test addition:
      for (int i = 0; i < 32; i++)
	{
	  x = x + x;
	}
      cout << "Addition test: " << x << endl;

      // Subtraction
      Natural sub = x - n;
      cout << "Subtraction test: " << sub << endl;

      // Division
      Natural div = x / n;
      cout << "Division test: " << div << endl;


      // Multiplication test
      for (int i = 0; i < 8; i++)
	{
	  x = x * n;
	}
      cout << "Multiplication test: " << x << endl;


      // Check the equality and < operators
      Natural y = n;
      if (y == 5)
	cout << y << " == " << 5 << endl;
      else
	{
	  cout << y << " != " << 5 << endl;
	  
	  if (y < 5)
	    cout << y << " <  " << 5 << endl;
	  else
	    cout << y << " >  " << 5 << endl;
	}
    }

  Natural factn = factorial(n);


  if (debugFlag == "-debug")
    cout << "Factorial of " << n << " is " << factn << endl;
  
  Natural odds = factn / ((factorial(k) * factorial(n-k)));

  cout << "Odds of winning are 1 in " << odds << endl;

  return 0;
}



Was This Post Helpful? 0
  • +
  • -

#38 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 08:51 PM

I think a few of the operators are not implemented proper and are calling the functions recursively.

eg This function keeps calling itself until there is a stack overflow (stack memory runs out) .

bool operator== (const Natural& i, const Natural& j)
{
  return i == j;
}



The lists would have to be checked against each other.
Was This Post Helpful? 1
  • +
  • -

#39 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 09:00 PM

Hmm, everything I try is private. i.nDigits, i.DigitList, etc.
Was This Post Helpful? 0
  • +
  • -

#40 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 09:10 PM

It will need to be a friend of the class to access members of the class.

If it is not to be a friend then it would call other functions that were members of the class.
.

This post has been edited by #define: 25 September 2013 - 09:11 PM

Was This Post Helpful? 1
  • +
  • -

#41 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 09:13 PM

I see, and I'm guessing I need to run it through every digit of the digitlist
Was This Post Helpful? 0
  • +
  • -

#42 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 09:41 PM

This is where I ended up, though I'm past deadline, now it's just a mission.

bool operator== (const Natural& i, const Natural& j)
{
   bool test = true;
   while (test == true)
   {
     while ((i.leadingDigit !=NULL && j.leadingDigit !=NULL))
     {
       if (i.leadingDigit == j.leadingDigit)
       {
         test = true;
       }
         else
       {
         test = false;
       }
       i.leadingDigit == i.leadingDigit->next;
       j.leadingDigit == j.leadingDigit->next;
       }
	 }    
  if (test == true)
  {
  return true;
  }
  else
  {
  return false;
  }
}

bool operator< (const Natural& i, const Natural& j)
{
   bool test = true;
   while (test == true)
   {
     while ((i.leadingDigit !=NULL && j.leadingDigit !=NULL))
     {
       if (i.leadingDigit - j.leadingDigit < 0)
       {
         test = true;
       }
         else
       {
         test = false;
       }
       i.leadingDigit == i.leadingDigit->next;
       j.leadingDigit == j.leadingDigit->next;
       }
	 }    
  if (test == true)
  {
  return true;
  }
  else
  {
  return false;
  }
}



This post has been edited by CoryMore: 25 September 2013 - 09:49 PM

Was This Post Helpful? 0
  • +
  • -

#43 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 10:21 PM

Do your functions work ok? The boolean seems to hang.

For the compare == operator I did this, basically it makes copies of the objects and the lengths are adjusted to be the same, then it is simpler to compare:

bool operator== (const Natural& k, const Natural& m)
{
  Natural ka = k;
  Natural ma = m;

  // equalize lengths
  while(ka.nDigits < ma.nDigits)
    ka.addLeadingZero();
  while(ma.nDigits < ka.nDigits)
    ma.addLeadingZero();

  Natural::DigitList* kp = ka.trailingDigit;
  Natural::DigitList* mp = ma.trailingDigit;

  while(kp != NULL) {
    // is digit the same
    if( kp->data != mp->data )
      return false;
    kp = kp->prev;
    mp = mp->prev;
  }

  return true;
}


Was This Post Helpful? 1
  • +
  • -

#44 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 111
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 10:40 PM

Yes, now there's an error in +=. I simply under thought this I believe.

I broke down and looked at the solution. Let me know if you're curious and would like me to send it.
Was This Post Helpful? 1
  • +
  • -

#45 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1371
  • View blog
  • Posts: 4,744
  • Joined: 19-February 09

Re: Errors implementing class functions "no match for operator"

Posted 25 September 2013 - 10:54 PM

Hi, no its ok I don't need an answer, thanks. I did the - operator in a similar fashion to the == operator. I just subtracted the digits from each other, and let the normalize function sort out any improper digits and it seemed to work ok.
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3