user7336243
user7336243

Reputation:

Overriding [] c++

I am currently writing my own String class. Here is the header

#pragma once

class String
{
private:
    char* m_Beginning;
    int m_Length;

public:
    // Constructors
    String();
    String(const String&);
    String(const char*);

    // Destructor
    ~String();

    // Operations
    String& operator=(const String&);
    String operator+(const String&)const;
    String& operator+=(const String&);
    char operator[](int _Index)const;

    // Methods
    void Append(const String&);
    String Concatenate(const String&)const;
    int Length()const { return m_Length; };
    void Clear();
};

And here is the class description

#include "String.h"
#include <cstring>
#include <iostream>

String::String()
{
    m_Beginning = nullptr;
    m_Length = 0;
}

String::String(const String& _String)
{
    m_Length = _String.Length();
    m_Beginning = new char[m_Length];
    for (int i = 0; i < m_Length; ++i)
    {
        m_Beginning[i] = _String[i];
    }
}

String::String(const char* _String)
{
    m_Length = strlen(_String);
    m_Beginning = new char[m_Length];
    for (int i = 0; i < m_Length; ++i)
    {
        m_Beginning[i] = _String[i];
    }
}

String::~String()
{
    delete[] m_Beginning;
}

String& String::operator=(const String& _String)
{
    Clear();
    m_Length = _String.Length();
    m_Beginning = new char[m_Length];
    for (int i = 0; i < m_Length; ++i)
    {
        m_Beginning[i] = _String[i];
    }
    return *this;
}

String String::operator+(const String& _String)const
{
    String NewString(*this);
    NewString += _String;
    return NewString;
}

String& String::operator+=(const String& _String)
{
    for (int i = 0; i < _String.Length(); ++i)
    {
        m_Beginning[m_Length + i] = _String[i];
    }
    m_Length += _String.Length();
    return *this;
}

char String::operator[](int _Index)const
{
    return m_Beginning[_Index];
}


void String::Append(const String& _String)
{
    *this += _String;
}

String String::Concatenate(const String& _String) const
{
    return (*this + _String);
}

void String::Clear()
{
    delete[] m_Beginning;
    m_Beginning = nullptr;
    m_Length = 0;
}

The thing I want to ask is how to override the operator [] so that I set a value to a certain cell, not just extract it.

str("ABCD");
str[2] = 'Z'; // and str will become "ABZD".

Thank you :)

Upvotes: 1

Views: 153

Answers (1)

Pavel P
Pavel P

Reputation: 16843

You need to return reference to the character within string's internal buffer. You also need to have const and non const versions of operator[] for your string.

In your String header:

const char& String::operator[](int _Index) const;
char& String::operator[](int _Index);

and in your .cpp file:

const char& String::operator[](int _Index) const
{
    return m_Beginning[_Index];
}

char& String::operator[](int _Index)
{
    return m_Beginning[_Index];
}

When you try to assign a character in your string using code like this:

str[2] = 'Z'; // and str will become "ABZD".

compiler will effectively generate code that is identical to this code:

{
  char& ch = str.m_Beginning[2];
  ch = 'Z';
}

Also, for the string case it's probably better to make these methods inline in header file. And another point, usually it's better to put an assert there to verify that index isn't out of bounds and that m_Beginning was allocated:

const char& operator[](int _Index) const
{
    assert(m_Beginning && _Index>=0 && _Index<m_Length);
    return m_Beginning[_Index];
}

char& operator[](int _Index)
{
    assert(m_Beginning && _Index>=0 && _Index<m_Length);
    return m_Beginning[_Index];
}

Upvotes: 2

Related Questions