Форум программистов, компьютерный форум CyberForum.ru

Как достать объект-контейнер, а не его элемент - C++

Восстановить пароль Регистрация
 
 
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
08.06.2014, 23:07     Как достать объект-контейнер, а не его элемент #1
Добрый вечер всем.

Возник вопрос.
Я читал Страуструпа и на одной из его глав, есть упражнение по созданию класса-контейнера, в котором также есть контейнеры (например vector и string).
Суть следующая:

У меня есть Структура S и шаблон, со своим распределителем памяти.
В структуре S есть указатель val, который хранит адрес 1-го элемента.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template <class T, class A = allocat<T> > struct S
{
private:
    unsigned int buffer;
    unsigned int size;
    T* val;
    A alloc;
public:
    //S(T t) : val(t) { cout << "Constructor called" << endl; }
 
    S() :size(0), buffer(0), val(0) { cout << "Default constructor called" << endl; }
    S(const unsigned int sz) :size(0), buffer(0), val(0) { resize(sz); }
    ~S() { alloc.deallocate(this->val, size); cout << "Destructor called" << endl; } //val && this->val
//===========================================================
    T& operator=(T&);
    istream& operator>> (istream&);
    T& operator[](unsigned int);
    const T& operator[](const unsigned int) const;
    T& get_val();
    void set_val(const T&);
    void read_val (T&);
//===========================================================
    void reserve(const unsigned int);
    void resize(const unsigned int);
    void push_back(const T&);
//===========================================================
};
Сам класс S должен уметь хранить в себе кучу объектов, причем некоторые объекты сами являются контейнерами.
Например, есть код:

C++
1
2
    S<string> s_string(3);
    S<vector <int> > s_vectors(4);
Само собой, я перегрузил оператор индексации, чтобы я мог получать нужный мне объект из моей структуры.
Но проблема вот в чём, при обращении к индексу моего класса, оператор индексации выводит не объект-контейнер, а объект в контейнере.
Т.е. я получаю не сам вектор, а его элемент.

C++
1
2
3
4
5
6
7
template <class T, class A>
const T& S<T,A>::operator[](unsigned int i) const
{
    //if (i < 0) throw Range_error(i);
    //if (i > size) throw Range_error(i);
    return val[i];
}
Сам я новичок, подскажите пожалуйста, что можно придумать, чтобы на запрос s_strings[1], получать не 1 char из строки, а всю строку, которая располагается по этому адресу указателя?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2014, 23:07     Как достать объект-контейнер, а не его элемент
Посмотрите здесь:

Контейнер map / свои стрктуры / вствить и достать. C++
C++ Как отсортирвоать контейнер, если его тип определяется по ходу выполнения программы? (динамическая идентификация типов)
C++ Как достать указатель на объект из контейнера set
C++ Работа со стеком (как достать элемент из стека?)
C++ STL. Создать объект-контейнер stack и заполнить его данными типа double
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2014, 23:20     Как достать объект-контейнер, а не его элемент #2
Цитата Сообщение от kordax Посмотреть сообщение
чтобы на запрос s_strings[1], получать не 1 char из строки, а всю строку, которая располагается по этому адресу указателя?
C++
1
return *val;
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
08.06.2014, 23:28  [ТС]     Как достать объект-контейнер, а не его элемент #3
return *val;
Но в таком случае:
C++
1
2
3
4
5
s_int[1] = 3;
s_int[2] = 25;
 
cout << s_int[1];
cout << s_int[2];
Выдают одно и тоже?
Предлагаете инкрементировать указатель?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2014, 23:31     Как достать объект-контейнер, а не его элемент #4
Странный контейнер с одним указателем. Може там массив указателей должен быть?
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
08.06.2014, 23:36  [ТС]     Как достать объект-контейнер, а не его элемент #5
Попробывал последний вариант - вроде всё тоже самое, видимо ошибка не в этом.
Просто у меня при вызове:
C++
1
2
S<string> s_string(3); //Создали объект S содержащий в себе объекты string.
s_string[0] = "t"; //Фигу с маслом, ошибка и вылет.
Странный контейнер с одним указателем. Може там массив указателей должен быть?
Странно, Страуструп так и делал вектор.
Но вообще у меня в allocator'е:
template<class T>
C++
1
2
3
4
5
6
7
T* allocat<T>::allocate(int n)
{
    if (n == 0) return NULL;
    T* p;
    p = (T*) malloc(n);
    return p;
}
Т.е. я выделаю память сразу под несколько объектов.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2014, 23:38     Как достать объект-контейнер, а не его элемент #6
Цитата Сообщение от kordax Посмотреть сообщение
Т.е. я выделаю память сразу под несколько объектов.
Понятно, указатель на массив объектов.
Попробуйте так:
C++
1
return *(val + i);
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
08.06.2014, 23:39  [ТС]     Как достать объект-контейнер, а не его элемент #7
1 return *(val + i);
Так и попробывал, не помогло

Попробывал последний вариант - вроде всё тоже самое, видимо ошибка не в этом.
Просто у меня при вызове:
C++
1
2
3
Код C++
S<string> s_string(3); //Создали объект S содержащий в себе объекты string.
s_string[0] = "t"; //Фигу с маслом, ошибка и вылет.
У Страуструпа также, но проблемы возникают если обращатсья к контейнеру в моём контейнере, если просто элемент вроде чара, инта и дабла - то проблем нету.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2014, 23:49     Как достать объект-контейнер, а не его элемент #8
Есть уже, увидел.
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
08.06.2014, 23:55  [ТС]     Как достать объект-контейнер, а не его элемент #9
Присваивание там не подходит (там же const везде). Если чтение (вывести) сделать?
У меня срабатывает другой оператор, который без const
template <class T, class A>
C++
1
2
3
4
5
6
T& S<T,A>::operator[](unsigned int i)
{
    //if (i < 0) throw Range_error(i);
    //if (i > size) throw Range_error(i);
    return *(val + i);
}
Для записи вот такой добавьте:
Да, такой есть, я случайно с const вставил в сообщение.

Но он также вылетает на присваивании, причем после ретурна.

Вывод благополучно вылетает на
C++
1
cout << "s_string = " << s_string[0] << endl;
Потому как не могу сделать присваивание и получается, что там ничего нет :/

Добавлено через 5 минут
Попробывал:
C++
1
2
    string str = "test";
    s_string.val[0] = str;
Вылетает также на этой операции, т.е. дело похоже не в моём операторе индексации.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.06.2014, 23:56     Как достать объект-контейнер, а не его элемент #10
Цитата Сообщение от kordax Посмотреть сообщение
S<string> s_string(3); //Создали объект S содержащий в себе объекты string.
Уверены, что после этого string в вашем контейнере есть? Пкажите откуда они там появляются.
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
09.06.2014, 00:01  [ТС]     Как достать объект-контейнер, а не его элемент #11
Уверены, что после этого string в вашем контейнере есть? Пкажите откуда они там появляются.
Нет, их нету, в конструкторе ничего не делал, хотя можно конечно.
Но вот
C++
1
2
string str = "test";
s_string.val[0] = str;
Даёт вылет, хотя val сделал публичным, всё компилируется.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.06.2014, 00:06     Как достать объект-контейнер, а не его элемент #12
Цитата Сообщение от kordax Посмотреть сообщение
Нет, их нету
Если их нет, то с чём действия производятся? С чем указатель связан? Куда по индексам обращаемся?

Добавлено через 3 минуты
Вот это string-и не создаст:
C++
1
2
3
4
5
6
7
T* allocat<T>::allocate(int n)
{
    if (n == 0) return NULL;
    T* p;
    p = (T*) malloc(n);
    return p;
}
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
09.06.2014, 00:07  [ТС]     Как достать объект-контейнер, а не его элемент #13
Если их нет, то с чём действия производятся? С чем указатель связан? Куда по индексам обращаемся?
Всё верно, но ведь
C++
1
2
string str = "test";
s_string.val[0] = str;
даёт вылет.

Как тогда присвоить, чтобы проверить вывод?

C++
1
2
3
4
5
6
7
T* allocat<T>::allocate(int n)
{
    if (n == 0) return NULL;
    T* p;
    p = (T*) malloc(n);
    return p;
}
Подскажите пожалуйста, чем заменить?
Проблема связана с тем, что у string свои механизмы выделения памяти?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.06.2014, 00:14     Как достать объект-контейнер, а не его элемент #14
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от kordax Посмотреть сообщение
Проблема связана с тем, что у string свои механизмы выделения памяти?
Нет, дело в том, что malloc(n) не конструирует объекты, тут просто выделение памяти размером n байтов. Используйте new.
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
09.06.2014, 00:18  [ТС]     Как достать объект-контейнер, а не его элемент #15
Нет, дело в том, что malloc(n) не конструирует объекты, тут просто выделение памяти размером n байтов. Используйте new.
Блин, задание именно в том, чтобы обойтись без new
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.06.2014, 00:29     Как достать объект-контейнер, а не его элемент #16
Цитата Сообщение от kordax Посмотреть сообщение
задание именно в том, чтобы обойтись без new
А в задании сказано, что контейнер может содержать и string-и?
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
09.06.2014, 00:32  [ТС]     Как достать объект-контейнер, а не его элемент #17
А в задании сказано, что контейнер может содержать и string-и?
Да, контейнер по-сути почти vector и содержит string.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.06.2014, 00:42     Как достать объект-контейнер, а не его элемент #18
Я так понимаю, что n - это количестов объектов, под которые нужно выделить память? Тогда:
C++
1
2
3
4
5
6
7
T* allocat<T>::allocate(int n)
{
    if (n == 0) return NULL;
    T* p;
    p = (T*) malloc(n * sizeof(T));
    return p;
}
А потом думайте, как эту память объектами string заполнить.

Добавлено через 4 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Я так понимаю, что n - это количестов объектов, под которые нужно выделить память?
Это так? Что в качестве значения параметра передаётся? Количество объектов или размер памяти?
kordax
 Аватар для kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
09.06.2014, 01:23  [ТС]     Как достать объект-контейнер, а не его элемент #19
Да, всё верно.
N это количество объектов, для которох мне нужно выделить память.
Т* allocate (int n) ; // выделяет память для п объектов типа Т
Добавлено через 29 минут
Да уж, заполнить память объектами string оказалось самым сложным в этой теме.
Похоже над этим придётся ещё недели 3 посидеть.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.06.2014, 02:22     Как достать объект-контейнер, а не его элемент
Еще ссылки по теме:

Может ли объект-член, или объект-элемент достучаться к содержащему его? C++
Достать нужный объект из контейнера C++
Если объект константный, означает ли это, что ни один его член-элемент или член-метод не изменится? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.06.2014, 02:22     Как достать объект-контейнер, а не его элемент #20
Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    T* allocat<T>::allocate(int n)
    {
        if (n == 0) return NULL;
        T* p;
        p = (T*) malloc(n * sizeof(T));
        for (int i = 0; i < n; ++i)
        {
            T obj;
            memcpy(p + i, &obj, sizeof(T));
        }
        
        return p;
    }
Yandex
Объявления
09.06.2014, 02:22     Как достать объект-контейнер, а не его элемент
Ответ Создать тему
Опции темы

Текущее время: 12:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru