Easier way to make class to work with operators?

﹥>﹥吖頭↗ 提交于 2020-01-04 03:58:11

问题


Here, I have a class called Value which simply can get and set float.

class Value
{
public:
    Value(float f)
    :f(f){};
    float get()
    {
        return f;
    }
    void set(float f)
    {
        this->f = f;
    }
private:
    float f;
};

And I want my class to be able to work like the following example.

Value value(3);
std::cout << value * 2 - 1 << std::endl; // -> 5
std::cout << value == 5 << std::endl; // -> true
value /= 2; 
std::cout << value << std::endl; // -> 2.5

Should I manually add all operator methods to my class?

Or would there be any easier solution to treat Value like float?


回答1:


Here is an idiomatic implementation of the relevant arithmetic, equality and stream operators.

Notes in the comments inline.

See also the note about the consequences/benefits of allowing implicit conversion from float.

#include <iostream>

class Value
{
public:
    // Note - this constructor is not explicit.
    // This means that in an expression we regard a float and a Value on the
    // right hand side of the expression as equivalent in meaning.
    // Note A.
    //      =
    Value(float f)
    :f(f){};

    float get() const
    {
        return f;
    }

    void set(float f)
    {
        this->f = f;
    }

    // Idiom: unary operators defined as class members
    // 
    Value& operator *= (Value const& r)
    {
        f *= r.f;
        return *this;
    }

    Value& operator -= (Value const& r)
    {
        f -= r.f;
        return *this;
    }

    Value& operator /= (Value const& r)
    {
        f /= r.f;
        return *this;
    }

private:
    float f;
};

// Idiom: binary operators written as free functions in terms of unary operators

// remember Note A? A float will convert to a Value... Note B
//                                                          =
auto operator*(Value l, Value const& r) -> Value
{
    l *= r;
    return l;
}

auto operator-(Value l, Value const& r) -> Value
{
    l -= r;
    return l;
}

auto operator<<(std::ostream& l, Value const& r) -> std::ostream&
{
    return l << r.get();
}

// Idiom: binary operators implemented as free functions in terms of public interface
auto operator==(Value const& l, Value const& r) -> bool
{
    return l.get() == r.get();
}

int main()
{
    Value value(3);
    // expressions in output streams need to be parenthesised
    // because of operator precedence
    std::cout << (value * 2 - 1) << std::endl; // -> 5
    // ^^ remember note B? value * 2 will resolve to value * Value(2) because of
    // implicit conversion (Note A)
    std::cout << (value == 5) << std::endl; // -> true
    value /= 2; 
    std::cout << value << std::endl; // -> 2.5
}



回答2:


Instead of get(), you could have a conversion operator to float type:

operator float() const { return f; }

If you also want to enable operations that change the value (such as /=), you can have similar non-const operator that returns a reference, or you can add those operators manually.

But if you want to have a class that behaves exactly like float, it might be better to use float instead of having the Value class at all.




回答3:


I implemented /= and == operators :

you can use of this page for learn more... https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

class Value
{
public:
    Value(float f) : f(f) {};

    operator float() const
    {
        return f;
    }

    void set(float f)
    {
        this->f = f;
    }

    Value &operator /=(float num)           // e.g. value /= 2;
    {
        this->f = f / num;
    }

    bool operator==(const float& a) const    // e.g. std::cout << value == 5 << std::endl; // -> true
    {
        if(this->f == a) return true;
            return false;
    }

private:
    float f;
};

main :

int main()
{
   Value value(10);

    value /= 5;

    cout << value << endl;
    cout << (value == 5) << endl;

return 0;
}


来源:https://stackoverflow.com/questions/51239390/easier-way-to-make-class-to-work-with-operators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!