0

i'm writing a class like this :

class Digit
{
    private :
        int *ref;
    public :
        Digit (int a) : ref(&a) {}
        int get_val ()
        {
            return (*ref);
        }
        Digit operator= (int &a)
        {
            if (a < 0 || a > 9)
                throw "invalid digit assignment.";
            (*ref) = a;
            return (*this);
        }
    };

so if someone define a digit ,he can not assign value more than 9 or less than 0 to it. the problem is, i also want to define another = operator, that he can assign a Digit to some value too. i tried something like this :

int operator= (int &a, Digit &d)
{
    a = d.get_value();
    return a;
}

but i get some error : 'int operator=(int&, Digit&)' must be a nonstatic member function

how can i fix this? how can i overload operator = with 2 arguments?

timrau
  • 22,578
  • 4
  • 51
  • 64
iambb5445
  • 15
  • 5
  • 1
    Why is `ref` a *pointer*? (It's also invalid as soon as the constructor returns.) – molbdnilo Apr 06 '17 at 15:46
  • 4
    Instead of thinking "how can I overload the assignment operator", think "how can I implicitly convert a `Digit` to an `int`". – molbdnilo Apr 06 '17 at 15:49
  • @molbdnilo i had to write a class with [] operator that returns digit so we can use it like : a[10] = 5; (and some member of a changes to 5.) – iambb5445 Apr 06 '17 at 15:55
  • @timaru i think so. so there is no way to do that? – iambb5445 Apr 06 '17 at 15:58
  • @iambb5445 -- Seems you need to properly document what operations you're looking for. Your current code has multiple issues, one being using a pointer to a temporary, the second is the unorthodox usage of `operator =` returning a new object instead of `*this` by reference, i.e. returning a `Date&`, not `Date`. – PaulMcKenzie Apr 06 '17 at 16:02
  • @PaulMcKenzie you are right about pointer to temporary, thanks for mentioning this. but i can't understand the second issue. can you explain it with more details please? – iambb5445 Apr 06 '17 at 16:12
  • @iambb5445 `Digit d(param); d = 5;` Since `d` has already been constructed, an assignment should just assign to the already constructed object and return that already constructed object by reference. Anything else is counter-intuitive (returning a new object, as your code attempts to do). – PaulMcKenzie Apr 06 '17 at 16:15
  • Standart says: `An assignment operator shall be implemented by a non-static member function with exactly one parameter`. So you can't implement it as free beenary operator. Use implicit/explicite convertion 'operator int()' – Ivan Pankov Apr 06 '17 at 16:17
  • @PaulMcKenzie i understand now. thanks a lot! i think i can fix this by changing it to : Digit& operator= (int a) – iambb5445 Apr 06 '17 at 16:21
  • @iambb5445 -- Yes, that should fix the return type. – PaulMcKenzie Apr 06 '17 at 16:26

2 Answers2

3

What you really need may be operator int().

class Digit {
   operator int() { return get_val(); }
};

Then you can write int a = d; assuming d is of class Digit.

timrau
  • 22,578
  • 4
  • 51
  • 64
  • That will solve the immediate issue, but as soon as the program becomes more involved, where `int` and `Digit` are being passed and returned, casting operators are more of a headache. There could be "silent" conversions going on where you least expect it to happen. – PaulMcKenzie Apr 06 '17 at 15:55
  • 2
    @PaulMcKenzie That can be solved by making the operator `explicit`. – NathanOliver Apr 06 '17 at 16:00
  • thanks a lot! that solved my problem. – iambb5445 Apr 06 '17 at 16:09
0

I think you are trying to get the value of the Digit as an int, if I understand correctly.

You aren't going to use operator = for that, because operator = is for assigning to the class. You want to extract a value from the class.

Your method:

 int get_val ()
 {
    return (*ref);
 }

Already does this. However, it should be

int get_val () const
{
    return (*ref);
}

because it does not change the value of any class members.

Usage would be:

int main()
{   
    Digit digit(5);
    int myInt = digit.get_value();
    return 0;
}

If you want to implicitly convert Digit to an int, you can use

operator int()
{
    return get_val();
}

which is just a shortcut. Without that operator, you'd do something like:

#include <iostream>

void Print(int x)
{
    std::cout << x << std::endl;
}

int main()
{   
    Digit digit(5);
    Print(digit.get_value());

    return 0;
}

but with the operator, you tell the compiler the Digit class may be treated (converted) like an int:

#include <iostream>

void Print(int x)
{
    std::cout << x << std::endl;
}

int main()
{   
    Digit digit(5);
    Print(digit);

    return 0;
}
Christopher Pisz
  • 3,757
  • 4
  • 29
  • 65