Вопрос об инициализации и индексации (наверное должно быть просто)

Модератор: Модераторы разделов

Аватара пользователя
rash
Сообщения: 14

Вопрос об инициализации и индексации

Сообщение rash »

Вот столкнулся с заковыкой - создать защищенный многомерный массив в C++
Написал следующее:

Код: Выделить всё

/*
 * ANSI C++ standard is used
 */

#include<iostream>
using namespace std;

/*
 * class vector - one dimensional array
 */

class vector {
    int *data;
    int max_index;
public:
    vector (int size);
    ~vector ();
    int &operator[] (int index);
};

vector::vector (int size=1)
{
    data = new int[size];
    max_index = size-1;
}

vector::~vector()
{
    delete data;
}

int &vector::operator[] (int index)
{
    if ((index < 0) || (index > max_index)) {
        cerr << "Range exceeded. Exiting" << '\n';
        exit (1);
    }

    return data[index];
}

/*
 * class matrix - two dimensional aray, methods
 * are using class vector
 */

class matrix {
    vector *data;
    int y_max_index;
public:
    matrix (int x_size, int y_size);
    ~matrix();
    vector &operator[] (int index);
};

matrix::matrix (int x_size=1, int y_size=1)
{
    data = new vector[y_size];                     /*<-- проблема здесь  */
    y_max_index = y_size-1;
}

matrix::~matrix()
{
    delete data;
}

vector &matrix::operator[] (int idx)
{
    if ((idx < 0) || (idx > y_max_index)) {
        cerr << "Range exceeded. Exiting" << '\n';
        exit(1);
    }
    return data[idx];
}

int main ()
{
    matrix arr(5,5);

    return 0;
}


Трудность возникла в конструкторе класса matrix - в момент, когда создается масив объектов vector, необходимо их инициализировать, а каким образом можно передать конструктору объектов vector параметр x_size? Ведь по умолчанию они создаются единичной длины, а хотелось бы, чтобы конструктор объекта matrix мог полностью управлять размером создаваемого массива.

--

И еще вопрос, чисто теоретический - как можно перегрузить оператор индексирования (квадратные скобки), чтобы можно было индексировать многомерные массивы? То есть передавать 2 и больше индексов.
Спасибо сказали:
Аватара пользователя
elide
Бывший модератор
Сообщения: 2421
Статус: Übermensch
ОС: лялих

Re: Вопрос об инициализации и индексации

Сообщение elide »

a юзать vector<vector<int>> уже не модно?
слава роботам!
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Вопрос об инициализации и индексации

Сообщение v04bvs »

Вашу задачу правильнее решать редизайном классов. В частности я бы наделил класс vector возможностью динамически менять размер и в конструкторе класса Matrix инициализировал бы соответственно. Или, если массив обязан быть константным - реализацией класса Vector как шаблона с целочисленным параметром-длиной.

Но, вообще говоря, то, что вы хотите, можно, и я покажу код, который это делает. Тем не менее использовать его не рекомендую. По крайней мере без кристального понимания того, что там происходит (а когда оно к вам прийдёт, вы не будете писать велосипеды :) )

Код: Выделить всё

#include <iostream>
using std::cout;
using std::endl;

class A {
public:
    A(int x) : x_(x) {}
    void foo() const { cout << x_ << " "; }

private:
    const int x_;
};

int main()
{
    A *v;
    const size_t size = 10;

    // Allocating array and manually calling constructors
    v = (A*)malloc(sizeof(A) * size);
    size_t i;
    try {
        for (i = 0; i < size; ++i)
            new(v + i) A(i);
    }
    catch (...) {
        for (size_t k = 0; k < i; ++k)
            v[k].~A();
        free(v);
        throw;
    }

    // Doing any actions
    for (size_t i = 0; i < size; ++i)
        v[i].foo();
    cout << endl;

    // Manually calling destructors and freeing array
    for (size_t i = 0; i < size; ++i)
        v[i].~A();
    free(v);

    return 0;
}



И еще вопрос, чисто теоретический - как можно перегрузить оператор индексирования (квадратные скобки), чтобы можно было индексировать многомерные массивы? То есть передавать 2 и больше индексов.

В рамках семантики многомерных массивов C - оно у вас уже должно работать, т.е.
Matrix a;
a[1][2] = 3;
В рамках семантики паскалеподобных языков, т.е. a[1, 2] - попробуйте задать несколько параметров оператору [], если не получится, то никак. Но, вообще говоря, массивы в С\С++ принято индексировать как [i][j][k] и отступать от этой традиции нежелательно.

Кстати у вас в коде ошибка - массив выделяется оператором new[] а удаляется оператором delete. Надо писать delete[] data; в деструкторе.
Спасибо сказали:
Аватара пользователя
rash
Сообщения: 14

Re: Вопрос об инициализации и индексации

Сообщение rash »

Или ... - реализацией класса Vector как шаблона с целочисленным параметром-длиной.

Вот, похоже это то, что нужно, спасибо.

Что касается второго вопроса - то я имел виду случай, например, если объект создает в своей закрытой части двумерный массив, и необходимо иметь возможность индексировать этот с помощью перегруженного оператора индексации, то есть без наследования одномерных массивов со своими перегруженными операторами.

И еще - по поводу delete[] - я в основном пользуюсь справочниками Шилдта, а в них о таком ни слова не встречал. Где можно прочитать подробнее, чтобы понять самому?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Вопрос об инициализации и индексации

Сообщение v04bvs »

rash писал(а): ↑
07.12.2006 01:49
Что касается второго вопроса - то я имел виду случай, например, если объект создает в своей закрытой части двумерный массив, и необходимо иметь возможность индексировать этот с помощью перегруженного оператора индексации, то есть без наследования одномерных массивов со своими перегруженными операторами.

Вряд ли это можно сделать. Без промежуточного класса тут никак.

И еще - по поводу delete[] - я в основном пользуюсь справочниками Шилдта, а в них о таком ни слова не встречал. Где можно прочитать подробнее, чтобы понять самому?

Даже не знаю, в любом учебнике по С++ это должно быть написано. Я Шилдта не читал, но думаю, вы что то пропустили.
Спасибо сказали:
Аватара пользователя
rash
Сообщения: 14

Re: Вопрос об инициализации и индексации

Сообщение rash »

Вряд ли это можно сделать. Без промежуточного класса тут никак.


Ясно, просто думал, что возможно я чего-то тут не знаю и не могу сообразить, потому что сам тоже никак не смог...

Даже не знаю, в любом учебнике по С++ это должно быть написано. Я Шилдта не читал, но думаю, вы что то пропустили.

Действительно, пропустил, только что специально посмотрел - в справочнике это есть, значит перед этим читал невнимательно.
Спасибо сказали: