Thread: Problem with class functions.

  1. #1
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256

    Problem with class functions.

    Code:
        class frac
         {
          public:
            frac(const double& d = 0);
            frac(const frac& f);
            frac operator = (const frac& f);
            frac operator *= (const frac& f);
            frac operator /= (const frac& f);
            frac operator += (const frac& f);
            frac operator -= (const frac& f);
            template<typename _VT>
            frac operator = (const _VT& v);
            template<typename _VT>
            frac operator *= (const _VT& v);
            template<typename _VT>
            frac operator /= (const _VT& v);
            template<typename _VT>
            frac operator += (const _VT& v);
            template<typename _VT>
            frac operator -= (const _VT& v);
            double aprox();
            int& numer(); 
            unsigned int& denom(); 
    //      private:
            int p_numer;
            unsigned int p_denom;
            void setaprox(double d);
            void simplify();
         };
    Code:
      int& frac::numer() { return p_numer; }
    Code:
      inline bool operator == (const frac& f1, const frac& f2)
       { return (f1.numer() == f2.numer() && f1.denom() == f2.denom()); }
    As you can guess, this is just a small piece of the full code, which I have based largely off of the standard #include file, "complex" , which I've attached if you care to look at it. Originally, I have p_numer and p_denom as public. Taking my cue off of the "complex" file I mentioned, I decided to make them private, and use a function that would return the value of those variables. What really bugs me is that I actually copied and pasted the declaration of the variable, the declaration of the function, the definition of the function, and the definition of the == operator, changed the variable names, and chaged the typename variables to int or unsigned int (the complex class is templated). I still get this error, though...
    Code:
    passing 'const std::frac' as 'this' argument of 'int& std::frac::numer()' discards qualifier
    every time I try to call the function, as in the == operator. And, of course, the same goes for the denom() function. Does anyone have any idea why this is? My best guess is that the complex class is templated, and mine isn't, but that just seems stupid...

  2. #2
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Why are you defining you numer as a reference to an int when you are just returning an int?
    And make your function const and you'll be ok
    Example :
    Code:
    #include <iostream>
    using namespace std;
    
    class tester
    {        
        public:
            tester()
            {
                this->number = 10;
            }
            const int &getNumber() const
            {
                return number;
            }
            inline bool operator==(const tester &t1)
            {
                return (t1.getNumber() == this->number);
            }
        private:
            int number;
    };
    
    int main()
    {
        tester t1;
        tester t2;
        if(t1 == t2)
        {
            cout<<"Woot"<<endl;
        }
        std::cin.get();
        return 0;
    }
    Last edited by prog-bman; 06-06-2005 at 09:55 PM.
    Woop?

  3. #3
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    You mean why does my function definition say it's returning an int reference, when it's really only returning an int? Well, really only becuase that's what the complex class does. But, I have tried the alternative and the errors that result are the same.

    However, I did just notice something.
    Code:
        bool operator == (const frac& f, const _VT& v)
       {
        frac f2 = v;
        return (f.numer() == f2.numer() && f.denom() == f2.denom());
       }
    In these callings of .numer() and .denom(), I receive no errors. I only get them on the bool operators that operate with two fracs.

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    The reason you are getting those errors is that your function to return your data is not a const function. Meaning that the function can modify data. So you want to add a const to the end of your function declaration as I did in the example above. If you want to return the reference return a const reference along with the const function.
    E.g.
    Code:
    const int &getNumber() const
    {
            return number;
    }
    Or the non-reference way.
    Code:
    int getNumber() const
    {
            return number;
    }
    Last edited by prog-bman; 06-06-2005 at 10:11 PM.
    Woop?

  5. #5
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Ahh. I was wondering if that had something to do with it. The complex class has one like that, and one in the style I used. Thanks a lot. I need to find a book to read on this stuff or something. :P

  6. #6
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    But now thinking,
    The reference way is better because it uses the actual data not a copy so it can be "faster".
    Oh and way to try to write your own stuff based on standard types it's fun .
    Woop?

  7. #7
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Thanks. I just came up with another question. Is it possible for me to write a.....I suppose it would be similar to a constructor.....that would cast my class as say, an int or a double. And can I define operators for types like int and double that will hande my class. Basically, instead of saying
    Code:
    int i; 
    frac f;
    i = f.aprox();
    could I say
    Code:
    i = f;
    and have the compiler do that for me? And could I do
    Code:
    printf("%f", float(f));
    rather than
    Code:
    printf("%f", f.aprox());
    ?

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    It's called "operator overloading" -- the operators being "=" and "type conversion". In C++, you can define an operator to do anything you want for your class. If you are so inclined, you can define "+" to multiply your objects by a constant, you can define "=" to subtract objects, and you can define type conversions to dispay "hello world".
    Last edited by 7stud; 06-07-2005 at 12:36 AM.

  9. #9
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    I know what operator overloading is. I've used it many many times, already. I'm talking about overloading an already defined operator, not an operator for my class.
    Code:
    class fraction
     {
      int numerator;
      int denominator;
      fraction operator = (const int& i)
       {
        numerator = i;
        denominator = 1;
       }
     };
    The bolded part is used when I'm assigning an int to a fraction. I want to make it possible to assign a fraction to an int.

    And my question on casting a class is still open.

  10. #10
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Nevermind
    Last edited by prog-bman; 06-07-2005 at 01:12 AM.
    Woop?

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    >>I want to make it possible to assign a fraction to an int.

    The conversion operator enables your class to specify how to do implicit conversions to other types. I don't have a compiler at work to run this code to confirm validity, but I think it's at least close and should encourage to look up the conversion operator and see what it can do for you.
    Code:
    struct Frac
    {
      int num;
      int den;
      operator unsigned short();  //conversion operator declared
    };
     
    Frac::opoertator unsigned short()  //conversion operator defined
    {
       return( int(num/den) );  //use integer math to truncate any decimal portion of result.  Cast result to an int so compiler doesn't give an error message.  Multiple other definitions possible.  
    }
     
    int main()
    {
       Frac f;
       f.num = 7;
       f.den = 3;
       int convertedFrac = f;  //one use of conversion operator
       cout << "convertedFrac:" << convertedFrac << endl;
    }
    You're only born perfect.

  12. #12
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Ahh. Thank you. So, the conversion operator accounts for both casting and assigning?

    And nevermind what, prog?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Replies: 3
    Last Post: 12-03-2001, 01:45 PM