Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7068791
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T05:22:02+00:00 2026-05-28T05:22:02+00:00

I am creating a 2D array class in C++. Everything works fine for a

  • 0

I am creating a 2D array class in C++. Everything works fine for a non-cost array.
I have yet to find a good explanation of const functions, and always seem to fumble around until it works. Now, however, I am at an impass.

Am I not understanding how to support const objects? Short of creating a second Row class, I can’t think of a solution, and that solution seems unnecessary.

main.cpp

#include "Array2D.h"
int main()
{
    int const x(1), y(1);
    Array2D<int> arr(3, 3);

    int value(0);
    for (int row(0); row < 3; ++row)
        for (int column(0); column < 3; ++column)
            arr[row][column] = ++value;
    std::cout << arr[x][y];

    Array2D<int> const carr(arr);
    //Everything's fine up to here


    std::cout << carr[x][y]; //Error

    std::cout << "\n\n[ PAUSE: Press ENTER to exit the program. ]";
    std::cin.get();
    return 0;
}

When I try to access carr[x][y] it throws an error, which is to be expected. So I included a const and non-const overload of operator[] in Array2D

Array2D.h

    template <typename T>
    class Array2D
    {
    public:
       //===============
      //CONSTRUCTORS
     //
        inline Array2D();
        inline Array2D(int rows, int columns = 0);
        inline Array2D(Array2D const &array2D);

       //===============
      //OPERATORS
     //
        inline Array2D<T>& operator=(Array2D const &array2D);
        inline Row<T> operator[](int index);
        inline Row<T> const operator[](int index) const;

       //===============
      //GETTERS
     //
        inline int getRows() const { return _rows; }
        inline int getColumns() const { return _columns; }

       //===============
      //SETTERS
     //
        inline void setRows(int rows);      //May result in loss of data
        inline void setColumns(int columns); //May result in loss of data

    //OTHER

        inline T& select(int row, int column);
        inline T const & select(int row, int column) const;

       //===============
      //DESTRUCTOR
     //
        inline ~Array2D(){}

    private:
       //===============
      //DATA
     //

        Array<T>    _array;     //Two dimensional array in row-major order
        int         _rows;      //The number of rows in the array
        int         _columns;   //The number of data in each row

       //===============
      //PRIVATE FUNCTIONS
     //
        //Initializes the array with current data
        inline void initArray2D();
        //Throws exception if length is negative
        inline void checkLength(int length) const;
        //Throws exception if index is out of bounds
        inline void checkIndex(int rowIndex, int columnIndex) const;
    };
//CONSTRUCTORS

template <typename T>
Array2D<T>::Array2D() : _array(0), _rows(0), _columns(0)
{ initArray2D(); }

template <typename T>
Array2D<T>::Array2D(int rows, int columns) : _array(0), _rows(rows), _columns(columns)
{
    checkLength(rows);
    checkLength(columns);

    initArray2D();
}

template <typename T>
Array2D<T>::Array2D(Array2D const &array2D)
{ (*this) = array2D; }

//OPERATORS

template <typename T>
Array2D<T>& Array2D<T>::operator=(Array2D const &array2D)
{   
    _rows = array2D._rows;
    _columns = array2D._columns;
    initArray2D();

    _array = array2D._array;
    return *this;
}

template <typename T>
Row<T> Array2D<T>::operator[](int index)
{
    return Row<T>(*this, index);
}
template <typename T>
Row<T> const Array2D<T>::operator[](int index) const
{
    Row<T> const toReturn(*this, index);;
    return toReturn;
}

//SETTERS

template <typename T>
void Array2D<T>::setRows(int rows)
{
    _array.setLength(rows * _columns);
}

template <typename T>
void Array2D<T>::setColumns(int columns)
{
    Array newArray(_rows * columns);

    //This will prevent truncated columns from being copied over
    int lesserColumn(columns > _columns ? _columns : columns);

    for (int row(0); row < _rows; ++row)
        for (int column(0); column < lesserColumn; ++column)
            newArray[row][column] = _array[row][column];
    _array = newArray;
}

//OTHER

template <typename T>
T& Array2D<T>::select(int row, int column)
{
    checkIndex(row, column);
    return _array[(row * column) + column];
}

template <typename T>
T const & Array2D<T>::select(int row, int column) const
{
    checkIndex(row, column);
    return _array[(row * column) + column];
}


// PRIVATE \\

template <typename T>
void Array2D<T>::initArray2D()
{
    _array = Array<T>(_rows * _columns);
}

template <typename T>
void Array2D<T>::checkLength(int length) const
{
    if (length < 0)
        throw Exception("LENGTH_LESS_THAN_ZERO");
}

template <typename T>
void Array2D<T>::checkIndex(int rowIndex, int columnIndex) const
{
    if (rowIndex >= _rows || columnIndex >= _columns)
        throw Exception("INDEX_LARGER_THAN_UPPER_BOUND");
    if (rowIndex < 0 || columnIndex < 0)
        throw Exception("INDEX_SMALLER_THAN_LOWER_BOUND");
}

The const functions seem to be in order, however an issue arises when it tries to create the Row object (explained in next paragraph) because it expects an Array2D&, but in the const function it passes a const Array2D&, which naturally does not work.

The idea of the Row object is to pass back something to handle the second [] operator without having to pass back array.

Row.h

template <typename T>
class Array2D;

template <typename T>
class Row
{
public:
   //==============
  //CONSTRUCTOR
 //
    inline Row(Array2D<T> &array2D, int row);

   //==============
  //OPERATORS
 //
    //The index will be validated by Array2D
    inline T& operator[](int column);
    inline T const & operator[](int column) const;

private:
   //==============
  //Data
 //
    Array2D<T>& _array2D;   //Source array
    int         _row;       //The row index
};

template <typename T>
Row<T>::Row(Array2D<T> &array2D, int row) : _array2D(array2D), _row(row)
{   }

template <typename T>
T& Row<T>::operator[](int column)
{
    return _array2D.select(_row, column);
}
template <typename T>
T const & Row<T>::operator[](int column) const
{
    return _array2D.select(_row, column);
}

Here is Array.h for reference

#pragma once

#include "Exception.h"

template <typename T>
class Array
{
public:
   //===============
  //CONSTRUCTORS
 //
    inline Array();
    inline Array(int length, int startIndex = 0);
    inline Array(Array const &copy);

   //===============
  //OPERATORS
 //
    inline Array& operator=(Array const &copy);
    inline T& operator[](int index);
    inline T const & operator[](int index) const;

   //===============
  //GETTERS
 //
    inline int getStartIndex() const { return _startIndex; }
    inline int getLength() const { return _length; }

   //===============
  //SETTERS
 //
    inline void setStartIndex(int index);
    inline void setLength(int length);

   //===============
  //DECONSTRUCTOR <coolface.jpg>
 //
    inline ~Array();

private:

   //===============
  //DATA
 //
    T*  _array;         //Pointer to array of type T
    int _length;        //Length of the array
    int _startIndex;

   //===============
  //PRIVATE FUNCTIONS
 //
    //Initializes the array with current LENGTH
    inline void init();

    //Throws exception if length is less than zero
    inline void checkLength(int length) const;

    //Throws exception if index is out of bounds
    inline void checkIndex(int index) const;

    //Copies contents of SOURCE to DESTINATION
    inline void copyArray(T * destination, T * source, int lastIndex);
};

//CONSTRUCTORS

template <typename T>
Array<T>::Array() : _array(0), _length(0), _startIndex(0) 
{ init(); }

template <typename T>
Array<T>::Array(int length, int startIndex = 0) : _array(0), _length(length), _startIndex(startIndex)
{
    checkLength(length);
    init();
}

template <typename T>
Array<T>::Array(Array const &copy)
{ (*this) = copy; }

//OPERATORS

template <typename T>
Array<T>& Array<T>::operator=(Array const &copy)
{
    _length = copy._length;
    _startIndex = copy._startIndex;
    init();
    copyArray(_array, copy._array, _length);
    return *this;
}

template <typename T>
T& Array<T>::operator[](int index)
{
    checkIndex(index);
    return _array[index - _startIndex];
}
template <typename T>
T const & Array<T>::operator[](int index) const
{
    checkIndex(index);
    return _array[index - _startIndex];
}

//SETTERS
template <typename T>
void Array<T>::setStartIndex(int index)
{ _startIndex = index; }

    // ! WARNING: Setting length to a lower value than current will result in lost data
template <typename T>
void Array<T>::setLength(int length)
{
    checkLength(length);

    T* oldArray(_array);
    int oldLength(_length);

    _length = length;
    init();

    int lastIndex(oldLength < _length ? oldLength : _length);
    copyArray(_array, oldArray, lastIndex);

    delete [] oldArray;
}

//DECONSTRUCT <coolface.jpg>
template <typename T>
Array<T>::~Array()
{
    delete [] _array;
}

// PRIVATE \\

template <typename T>
void Array<T>::init()
{
    _array = new T[_length];
}

template <typename T>
void Array<T>::checkLength(int length) const
{
    if (length < 0)
        throw Exception("LENGTH_LESS_THAN_ZERO");
}

template <typename T>
void Array<T>::checkIndex(int index) const
{
    if (index - _startIndex >= _length)
        throw Exception("INDEX_LARGER_THAN_UPPER_BOUND");
    if (index - _startIndex < 0)
        throw Exception("INDEX_SMALLER_THAN_LOWER_BOUND");
}

template <typename T>
void Array<T>::copyArray(T * destination, T * source, int lastIndex)
{
    while (lastIndex--)
        destination[lastIndex] = source[lastIndex];
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T05:22:02+00:00Added an answer on May 28, 2026 at 5:22 am

    Sadly, I think you’ll need two versions of Row: one for const Array and one for non-const. Just like the standard containers have iterators and const_iterators.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Im creating a dependent dropdown & everything works fine for me. CHtml::dropDownList('country_id','', array(1=>'USA',2=>'France',3=>'Japan'), array(
I'm creating my own JavaScript Array-like object and I have methods that call closures.
I am creating non-namespaced classes dynamically. I have seen an example where this creation
I'm creating a generic list class that has a member of type Array(Array of
So I have a class foo that has a method which returns an array
I am creating a json array in PHP like this (it's inside a class):
Sorry for asking silly question.. I have an array with class objects like: Class
I am creating an array of string objects in PowerShell which needs to be
Why is it that for user defined types when creating an array of objects
When creating a 3D array in C#, which is a better way to create

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.