Overloading Subscript or array index operator [] in C++
Last Updated :
02 Jul, 2024
The Subscript or Array Index Operator is denoted by '[]'. This operator is generally used with arrays to retrieve and manipulate the array elements. This is a binary or n-ary operator and is represented in two parts:
- Postfix/Primary Expression
- Expression
The postfix expression, also known as the primary expression, is a pointer value such as array or identifiers and the second expression is an integral value. In the second expression we can also include the enumerated values.
Syntax:
postfix-expression[expression];
Example: Ramswarup[10];
Here the Ramswarup is an array and the above
statement print the value which is held by
Ramswarup at index position 10.
The primary-expression followed by the subscript operator is the pointer and it can be an integral value but the one must keep in mind that one of expression among two expressions must be a pointer value and it does not matter whether the second one is of an integral order or not.
Example:
CPP
// CPP program to demonstrate []
// operator
#include <iostream>
using namespace std;
int main()
{
char name[] = "Ramswarup Tushar Nilesh Subhash";
// Both of the statement prints same thing
cout << name[5] << endl;
cout << 5 [name] << endl;
return 0;
}
Explanation:
In the above example both "cout" statement provides similar output due to the exclusive property of the subscript operator. The compiler reads both the statement in a similar way, so there is no difference between the *(name + 5) and the *(5 + name).
Positive and Negative Subscripts
The first element of an array is stored at index 0. The range of a C++ array is from array[0] to array[size - 1]. However, C++ supports positive and negative subscripts. Negative subscripts must fall within array boundaries; if they do not, the results are unpredictable. The following code shows positive and negative array subscripts:
CPP
// CPP program illustrating the
// positive and negative subscripts
#include <iostream>
using namespace std;
// Driver Method
int main()
{
int intArray[1024];
for (int i = 0, j = 0; i < 1024; i++) {
intArray[i] = j++;
}
// 512
cout << intArray[512] << endl;
// 257
cout << 257 [intArray] << endl;
// pointer to the middle of the array
int* midArray = &intArray[512];
// 256
cout << midArray[-256] << endl;
// unpredictable, may crash
cout << intArray[-256] << endl;
}
Output512
257
256
60426920
The negative subscript in the last line can produce a run-time error because it points to an address -256 positions which can be lower in memory than the origin of the array. The pointer midArray is initialized to the middle of intArray; it is therefore possible (but not recommended) to use both positive and negative array indices simultaneously. Array subscript errors do not generate compile-time errors, but they might yield unpredictable results. We have introduced Operator Overloading. In this post overloading of index operator [] is discussed. Following are some useful facts about overloading of [].
- Overloading of [] may be useful when we want to check for index out of bound.
- We must return by reference in function because an expression like "arr[i]" can be used an lvalue.
Following is C++ program to demonstrate overloading of array index operator [].
CPP
// Overloading operators for Array class
#include <cstdlib>
#include <iostream>
using namespace std;
// A class to represent an integer array
class Array {
private:
int* ptr;
int size;
public:
Array(int*, int);
// Overloading [] operator to access elements in array
// style
int& operator[](int);
// Utility function to print contents
void print() const;
};
// Implementation of [] operator. This function must return
// a reference as array element can be put on left side
int& Array::operator[](int index)
{
if (index >= size) {
cout << "Array index out of bound, exiting";
exit(0);
}
return ptr[index];
}
// constructor for array class
Array::Array(int* p = NULL, int s = 0)
{
size = s;
ptr = NULL;
if (s != 0) {
ptr = new int[s];
for (int i = 0; i < s; i++)
ptr[i] = p[i];
}
}
void Array::print() const
{
for (int i = 0; i < size; i++)
cout << ptr[i] << " ";
cout << endl;
}
// Driver program to test above methods
int main()
{
int a[] = { 1, 2, 4, 5 };
Array arr1(a, 4);
arr1[2] = 6;
arr1.print();
arr1[8] = 6;
return 0;
}
Output1 2 6 5
Array index out of bound, exiting
Const-Correctness
Overloading both const and non-const versions of the subscript operator ([]) ensures that elements can be accessed in a read-only manner when the object is const, preventing unintended modifications to const data types.
Implementing both versions of the subscript operator is a best practice in C++ to maintain clarity and adhere to const-correctness principles, enhancing code safety and predictability.
Example:
C++
#include <cstdlib>
#include <iostream>
using namespace std;
// A class to represent an integer array
class Array {
private:
int* ptr;
int size;
public:
Array(int*, int);
// Overloading [] operator to access elements in array
// style
int& operator[](int);
const int& operator[](int) const;
// Utility function to print contents
void print() const;
};
// Implementation of non-const [] operator. This function
// must return a reference as array element can be put on
// the left side
int& Array::operator[](int index)
{
if (index >= size) {
cout << "Array index out of bound, exiting";
exit(0);
}
return ptr[index];
}
// Implementation of const [] operator. This function allows
// read-only access
const int& Array::operator[](int index) const
{
if (index >= size) {
cout << "Array index out of bound, exiting";
exit(0);
}
return ptr[index];
}
// Constructor for array class
Array::Array(int* p = NULL, int s = 0)
: size(s)
, ptr(NULL)
{
if (s != 0) {
ptr = new int[s];
for (int i = 0; i < s; i++)
ptr[i] = p[i];
}
}
// Utility function to print contents
void Array::print() const
{
for (int i = 0; i < size; i++)
cout << ptr[i] << " ";
cout << endl;
}
// Driver program to test above methods
int main()
{
int a[] = { 1, 2, 4, 5 };
Array arr1(a, 4);
arr1[2] = 6;
arr1.print();
// Uncommenting the next line will cause an error
// because the index is out of bounds arr1[8] = 6;
const Array arr2(a, 4);
cout << arr2[2] << endl;
// Uncommenting the next line will cause an error
// because arr2 is const and cannot modify its elements
// arr2[2] = 7;
return 0;
}
Similar Reads
Increment (++) and Decrement (--) Operator Overloading in C++ Operator overloading is a feature in object-oriented programming which allows a programmer to redefine a built-in operator to work with user-defined data types. Why Operator Overloading? Let's say we have defined a class Integer for handling operations on integers. We can have functions add(), subtr
4 min read
Rules for operator overloading In C++, following are the general rules for the things that are not allowed with operator overloading. 1) Only built-in operators can be overloaded. New operators can not be created. 2) Arity of the operators cannot be changed. 3) Precedence and associativity of the operators cannot be changed. 4) O
3 min read
array::operator[ ] in C++ STL Array classes are generally more efficient, light-weight, and reliable than C-style arrays. The introduction of array class from C++11 has offered a better alternative for C-style arrays. array::operator[] This operator is used to reference the element present at position given inside the operator.
2 min read
array get() function in C++ STL The array::get() is a built-in function in C++ STL which returns a reference to the i-th element of the array container. Syntax: get(array_name) Parameters: The function accepts two mandatory parameters which are described below. i - position of an element in the array, with 0 as the position of the
2 min read
Why Use Iterators Instead of Array Indices? In C++, both iterators and array indices are used to access and manipulate elements in a container, such as arrays, vectors, and lists. However, one common question that arises is why should we prefer using iterators over array indices in certain scenarios?In this article, we will learn the advantag
3 min read
Vector operator[ ] in C++ STL In C++, the vector operator [] is used to randomly access or update the elements of vector using their indexes. It is similar to the vector at() function but it doesn't check whether the given index lies in the vector or not.Letâs take a look at a simple code example:C++#include <bits/stdc++.h
3 min read
Vector Operator = in C++ STL In C++, the vector operator = is used to assign the contents of one vector to another. It allows you to copy elements from one vector to another or initialize a vector with another vector's contents.Letâs take a look at a simple code example:C++#include <bits/stdc++.h> using namespace std; int
3 min read
Pointers vs Array in C++ Arrays and pointers are two derived data types in C++ that have a lot in common. In some cases, we can even use pointers in place of arrays. But even though they are so closely related, they are still different entities. In this article, we will study how the arrays and pointers are different from e
3 min read
How to declare a 2D array dynamically in C++ using new operator Prerequisite: Array BasicsIn C/C++, multidimensional arrays in simple words as an array of arrays. Data in multidimensional arrays are stored in tabular form (in row major order). Below is the general form of declaring N-dimensional arrays: Syntax of a Multidimensional Array: data_type array_name[si
4 min read
Pointer to an Array in C++ Pointers in C++ are variables that store the address of another variable while arrays are the data structure that stores the data in contiguous memory locations. In C++, we can manipulate arrays by using pointers to them. These kinds of pointers that point to the arrays are called array pointers or
6 min read