--- title: C++ --- # C++ ## Why `operator[]` returns a reference ```c++ class IntList { private: int m_list[10]{}; public: int& operator[] (int index); }; int& IntList::operator[] (int index) { return m_list[index]; } ``` Let’s take a closer look at how `list[2] = 3` evaluates. Because the subscript operator has a higher precedence than the assignment operator, `list[2]` evaluates first. `list[2]` calls `operator[]`, which is defined to return a reference to `list.m_list[2]`. Because `operator[]` is returning a reference, it returns the actual `list.m_list[2]` array element. The partially evaluated expression becomes `list.m_list[2] = 3`, which is a straightforward integer assignment. Any value on the left hand side of an assignment statement must be an l-value (which is a variable that has an actual memory address). Because the result of `operator[]` can be used on the left hand side of an assignment (for example `list[2] = 3`), the return value of `operator[]` must be an l-value. As it turns out, references are always l-values, because you can only take a reference of variables that have memory addresses. So by returning a reference, the compiler is satisfied returning an l-value. Consider what would happen if `operator[]` returned an integer by value instead of by reference. `list[2]` would call `operator[]`, which would return the value of `list.m_list[2]`. For example, if `m_list[2]` had the value of 6, `operator[]` would return the value 6. `list[2] = 3` would partially evaluate to `6 = 3`, which makes no sense. If you try to do this, the C++ compiler complains: C:VCProjectsTest.cpp(386) : error C2106: '=' : left operand must be l-value Taken from [Overloading the Subscript Operator](https://www.learncpp.com/cpp-tutorial/overloading-the-subscript-operator/). ### Necessity of a virtual destructor for an abstract class A virtual destructor is essential for an abstract class because an object of a derived class is usually manipulated through the interface provided by its abstract base class. In particular it may be deleted through a pointer to a base class. Then the virtual function call mechanism ensures that the proper destructor is called. That destructor then implicitly invokes the destructors of its bases and members.