简体   繁体   中英

A custom Vector and Matrix class in C++ and operator[]

I have a vector class in C++ that relies on raw pointer. I dont use std::vector as I need to create vector objects from raw pointers for specifal cases. Here is very simple example of my class:

template <typename T>
class Vector
{ ...
  private:
    T * m_data; int m_size; bool dontFree; ...
  public:
    Vector(T *const ptr, int size) { m_data = ptr; m_size = size; dontFree = true; }
    Vector(int size, T val) {  ...  dontFree = false; }
    ~Vector(): {   if(!dontFree) delete [] m_data; }
    T& operator[](const size_type index);
};

Similarly I have the matrix data type that also stores data in raw pointer and can use vector to support [][] as it is not allowed in C++, something like:

template<typename T>
class Matrix
{
  private:
   T * m_data; ...

 public:
  ... 
  Vector<T>& operator[](const int rowIndex)
  {
     return Vector<T>(&m_data[rowSize * rowIndex], rowSize);
  }
}

How could I do efficiently implement operator[] for matrix returing a Vector so that I can write code, something follow:

Matrix<int> m(5,5);
m[1][1] = 10;
int temp = m[1][2];

Please suggest considering the overhead of copy constructor etc.

Create a proxy class that overloads operator[] that you can give access to your matrix's array. Something like this:

template<typename T>
class Proxy
{
public:
    Proxy(T * tp)
        :rowStart(tp)
    {}

    T & operator[](const int columnIndex)
    {
        return rowStart[columnIndex];
    }

private:
    T * rowStart;
};

Then your Matrix class' operator[] can return one of these, like this:

Proxy<T> operator[](const int rowIndex)
{
     return Proxy<T>(m_data + rowSize * rowIndex);
}

It's not complete of course, but it should get you started.

You should return vector by value to make your code correct. Also you can write a small proxy if your vector does a lot of work inside a copy constructor.

If you implement your operator[] as inline method (eg don't move implementation to cpp) then good compiler should optimize your code and eliminate unnecessary copying.

But if you are crazy about performance then you can return a raw pointer from the operator:

... 
T* operator[](const int rowIndex)
{
  return m_data + rowSize * rowIndex;
}
...
int temp = m[1][2];

But is a dangerous approach!

The recommendation when implementing multidimensional matrices is not to overload operator[] , but rather overload operator() with multiple dimensions. There are a few reasons that you can read in the C++ FAQ lite

template <typename T>
class Matrix {
public:
   typedef std::size_t size_type;
   typedef T & reference;
   typedef T const & const_reference;

   const_reference operator()( size_type x, size_type y ) const;
   reference operator()( size_type x, size_type y );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM