Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to overload accessor and mutator operator[] in c++

I want to write a String class. And want to use subscript to access element in my String. So, I write two member function, one to get the element in the String, and another to set the element in the String. Please look at following code;

#include <iostream>
#include <algorithm>

using namespace std;

class String {
public:
    String();

    String(const char *s);

    char &operator[] (int index);
    char operator[] (int index) const;

private:
    char *arr;
    int len;
};

String::String() {
    arr = new char[1];
    arr[0] = '\0';
    len = 0;
}

String::String(const char *s) {
    len = strlen(s);
    arr = new char[len + 1];
    std::copy(s, s + len + 1, arr);
}

//mutator operator[] ---> used to change data members;
char& String::operator[](int index)
{
    cout << "mutator []" << endl;
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];
}
//Accessor operator[]---> used to read data members
char String::operator[](int index) const
{
    cout << "accessor []" << endl;
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];
}

int main()
{
    String s1 = "abc";

    s1[1] = 'b';  //---> should use mutator operator
    String s2 = "efg";
    s2[1] = s1[2]; //---> should use both accessor and mutator operator
    char a = s1[2]; //---> should use accessor operator
    cout << s2[1] << endl; //---> should use accessor operator
}

when I run this code. It's outputs are all mutator; It confuses me a lot;

like image 828
sydridgm Avatar asked Dec 06 '22 19:12

sydridgm


1 Answers

Let's see this case with the point of view of the compiler. I present you this code:

String s2;

/* things */ s1[2] /* things */

What function do you choose? The accessor or the mutator? Since s2 is not a const object, let's take the non-const version!

That's why your code is always printing mutator, the compiler will not choose which function to call depending of what you do with the result. Whether you call the char's assignment operator or not.

And your const version should not return a copy, but a const reference:

char& operator[](size_t index);
const char& operator[](size_t index) const;

You will get a compilation error instead of a value not assigned if you try to write into a const string.

like image 89
Guillaume Racicot Avatar answered Dec 18 '22 18:12

Guillaume Racicot