0

I'm trying to reverse the string from the FunnyNumber class. The problem is that when I call the method reverse in main on f2, it doesn't reverse the f2 string. But when I print out the reversed string from the reverse method implementation, it works. Also I overloaded the << operator to print out the string value in the class Number which is inherited in FunnyNumber class. Any help would be appreciated.

#ifndef NUMBER_H
#define NUMBER_H

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

class Number {
public:
  // Make a number with value 0
  Number();
  // Make a number with value val
  Number(string val);

  // Get the number's value
  virtual string getValue() const;

  // Print this number to the stream
  virtual void print(ostream& stream) const;

  // Read this number from the stream
  virtual void read(istream& stream);

  // Overload the insertion operator
  friend ostream& operator <<(ostream& outs, const Number& n);

  // Overload the extraction operator
  friend istream& operator >> (istream& ins, Number& n);

protected:
  string value;
};

#endif 


Number::Number()
{
  value = "";
}
Number::Number(string args)
{
  value = args;
}
string Number::getValue()const
{
  return value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
  n.print(outs);
  return outs;
}
void Number::print(ostream& stream)const
{
  stream << getValue();
}
void Number::read(istream& stream)
{
  stream >> value;
}
istream& operator >> (istream& ins, Number& n)
{
  n.read(ins);
  return ins;
}

#ifndef FUNNYNUMBER_H
#define FUNNYNUMBER_H

#include<iostream>
#include<string>
#include"Number.h"
#include<algorithm>


using namespace std;

class FunnyNumber : public Number 
{
public:
    FunnyNumber();
    FunnyNumber(string val);
    virtual string operator+(const FunnyNumber &other)const;
    virtual bool operator==(const FunnyNumber &other)const;
    void reverse();
    int find_first_not_this(char a);

protected:
    string value;

};
#endif // !FUNNYNUMBERS_H

FunnyNumber::FunnyNumber()
{
    value = "";
}

FunnyNumber::FunnyNumber(string val) : Number(val)
{
    value = val;
}

string FunnyNumber::operator+ (const FunnyNumber& other)const
{
    return getValue() + other.getValue();
}
int FunnyNumber::find_first_not_this(char a)
{
    int pos = 0;

    for(int i = 0; i < value.length(); i++)
    {
        if(value[i] != a)
        {
            pos = i;
            return pos;
        }
    }
    return pos;
}
bool FunnyNumber::operator==(const FunnyNumber& other)const
{
    bool isEqual = true;
    for (int i = 0; i < other.getValue().length(); i++) 
    {
        bool found = false;
        for (int j = 0; j < getValue().length(); j++) 
        {
            if(getValue()[j] == other.getValue()[i])
            {
                found = true;
                break;
            }
        }
        if(!found)
        {
            isEqual = found;
            return isEqual;
        }
    }
    return isEqual;
}

void FunnyNumber::reverse()
{
    std::reverse(value.begin(), value.end());
    value.erase(0, find_first_not_this('0'));
}


#include <iostream>
#include<string.h>
#include "FunnyNumber.h"

using namespace std;

int main()
{
   FunnyNumber f2;
   f2 = FunnyNumber("223");
   f2.reverse();
   cout<<"Reversed value "<<f2<<endl;

   system("pause");
   return 0;
}

output is 223 instead of 322

tildawn28
  • 9
  • 2

2 Answers2

2

Your FunnyNumber stores the value twice, once in a subobject of type Number, and once in string FunnyNumber::value.

Your reverse function modifies the second one, but doesn't have any effect on the Number base subobject. And then the only output function you call is working on the Number base subobject, and knows nothing about string FunnyNumber::value. That's why what is printed is not the result of reversal.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • So to fix it I should overload the operator << in the FunnyNumber class too? – tildawn28 May 29 '17 at 04:22
  • @tildawn28: That would be *a* solution, probably not the best one, because it means that any other circumstance that `FunnyNumber` is used in place of a `Number`, the reversed string won't be used. But it's hard to talk about better solutions since you haven't shown the `Number` source code. – Ben Voigt May 29 '17 at 04:25
  • @tildawn28: Ok, all you need to do is remove `protected: string value;` from `FunnyNumber`, which is hiding the one inside `Number`. Once you do, your reversal function will change `string Number::value` in the base subobject of `FunnyNumber`, affecting everything that uses a `FunnyNumber` polymorphically, including the `operator<<`. – Ben Voigt May 29 '17 at 05:21
  • This is way better than my solution +1. – Manvir May 29 '17 at 05:33
0

the overloaded operator << is a friend function on the Number class and friend functions are not inherited.

class Number {
public:
  // Make a number with value 0
  Number();
  // Make a number with value val
  Number(string &val);

  // Get the number's value
  virtual string getValue() const;

  // Print this number to the stream
  virtual void print(ostream& stream) const;

  // Read this number from the stream
  virtual void read(istream& stream);

  // Overload the insertion operator
  friend ostream& operator <<(ostream& outs, const Number& n);

  // Overload the extraction operator
  friend istream& operator >> (istream& ins, Number& n);

protected:
  string *value;
};
Number::Number()
{
    value = NULL;
}
Number::Number(string &args)
{
  value = &args;
}
string Number::getValue()const
{
  return *value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
  n.print(outs);
  return outs;
}
void Number::print(ostream& stream)const
{
  stream << getValue();
}
void Number::read(istream& stream)
{
  stream >> *value;
}
istream& operator >> (istream& ins, Number& n)
{
  n.read(ins);
  return ins;
}
Manvir
  • 769
  • 1
  • 7
  • 15
  • oh ok I see for some reason I thought friend functions were inherited too – tildawn28 May 29 '17 at 03:39
  • Friend functions aren't inherited, but they will be used for instances of derived classes. The bug is caused by something else. – Ben Voigt May 29 '17 at 04:08
  • this is what I came up with you can make the value in class number a pointer. tell me if this works – Manvir May 29 '17 at 05:08