I was following a tutorial on https://www.learncpp.com/ but I have some doubts...I have a simple class with many overloaded operators and a few member functions. I do not know where should I put const and which method should return-by reference and which by-value. For the simplicity let us say that it is a box with numbers:
class Box {
 private:
    unsigned int d;  // dimension
    float *arr;  // elements
 public:
    explicit Box(unsigned int arg_d, float* arg_arr);
    Box(const Box& B);
    Box() = delete;
    ~Box();
    float _() const { return d; }
    float norm() const;
    Box inv() const;
    Box expand(unsigned int arg_d);
    Box operator~ () const;
    Box operator- () const;
    Box& operator= (const Box &B);
    float& operator[] (unsigned int i);
    const float& operator[] (unsigned int i) const;
    Box& operator+= (const Box &B);
    Box& operator-= (const Box &B);
    Box& operator*= (const Box &B);
    Box& operator^= (const unsigned int x);
    Box& operator/= (const Box &B);
};
- Many operators (and a copy constructor too) take const arguments. Do I have to write non-const versions too?
- Some operator (as well as the method _()) have a keyword const after the argument list. Should I have that for all? Or should I write two versions of everything?
- Should I mark the return type as const like in the []operator? Right now this one has two versions, should it be like that? Let's say I would allow for modification of class element with[]. Should I even write const version? Let's say I do not allow it - should I even write non-const version?
- Operators which are linked with assignment return by-reference (I found that in the tutorial). Is that correct? Should other operators, like ~and-which return new objects also return by reference?
On top of that I have overloaded the operators globally too:
bool operator== (const Box &B1, const Box &B2);
bool operator!= (const Box &B1, const Box &B2);
Box operator+ (const Box &B1, const Box &B2);
Box operator- (const Box &B1, const Box &B2);
Box operator* (const Box &B1, const Box &B2);
Box operator^ (const Box &B, const unsigned int x);
Box operator/ (const Box &B1, const Box &B2);
- Do I have to write versions which accept non-const arguments too?
- Should these operators have const keyword at the end, like []previously? I guess not, since then the new object could not be modified? Or am I confusing the const that appears before return type with the const after the argument list? What is the difference?
- Should these operators return a new Boxby reference, as for their assignment-chained counterparts?
