2.3 KiB
title |
---|
C++ |
C++
Why operator[]
returns a reference
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.
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.