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

в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 5.00
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
26.06.2011, 22:40     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #1
Собсно


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Это типа служебного класса. (Внимание! В оригинальном коде он вложен в класс xx, но я этого не стал делать, дабы не усложнять код!)
class nemo_ {
};
 
//А это вот класс для конечного пользователя
class xx {
 public:
  nemo_& funktsia () {
  nemo_* ne= new nemo_ [1];
  return *ne;
 };
};
 
int main () {
 xx m;
 
 //Так, вот щас создастся объект класса nemo_; а нужен он для того, чтобы выполнился определённый код, который в нём скрывается
 m.funktsia ();
 //Тут пойдёт всякий разный код, и мне объект nemo_ больше не нужен
}
Вот как удалить объект класса nemo? Указателя не него в main нет, создать указатель в main НЕ ПРЕДЛАГАТЬ ибо это что же получается, конечный пользователь будет пользоваться классом xx и потом ещё должен будет заботиться об удалении nemo_, о котором он знать ничего не знает? Это не наш метод, наш метод даже не знаю какой, по-моему придётся смириться с утечкой памяти, пусть после m.funktsia (); объект типа nemo_ существует до конца проги. Так что ли?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2011, 22:40     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант!
Посмотрите здесь:

C++ Не создаётся объект класса
У меня класс B в классе A, а в классе B рекурсивная функция переопределения оператора "()", как её вызвать, не создавая явно объект класса B? C++
Не создаётся объект string на ровном месте! Почему? C++
C++ Беда с оператором DELETE
C++ Прочитать никнейм из файла и после использования - удалить
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 18:57     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #41
Цитата Сообщение от kravam Посмотреть сообщение
Он рабочий и он нужен. Как нужен конструктор пустой строки или пустого вектора, ОК?
сам проверь. Создай хоть один объект своим конструктором по умолчанию. Получишь Undefined behavior. Потому что конструктор по умолчанию и деструктор в твоей программе не совместимы. Хотя в данном случае прога отработает почти до конца и лишь потом вывалится в дебаг, но утешение слабенькое

Цитата Сообщение от kravam Посмотреть сообщение
"лучше перегружать оператор(), а то так ты получается даёшь пользователю поиграться с указателями matrix[]" Это ты что предлагаешь?
matrix () (); matrix () [] или matrix [] ()?
нет, я предлагал перегрузить оператор().
matrix(x, y);
не знаю насколько это гениально, но всяко лучше matrix[][] на порядок, хотя бы тем что не нарушает инкапсуляцию.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.06.2011, 19:50     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #42
Цитата Сообщение от pito211 Посмотреть сообщение
matrix(x, y);
не знаю насколько это гениально
в бусте именно так)
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
27.06.2011, 19:54  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #43
silent_1991, ну нравится вам этот код, Бога ради; если вы считаете что глазу милее:
C++
1
Row< T > *m_matrix;
нежели
C++
1
T** p
; у нас демократия, знаете ли. С точки зрения не читаемости, а внутренней реализации, так я в ваш код не вникал, а в своём ничего нового не придумал. Указатель на указатель на элемент типа T, сермяжное выделение памяти, сермяжное возвращение.
Не умыли вы меня. Ну да, имеет право на существование ваш код. Пусть он будет. Хай живе ПНС! Только комменты пишите в следующий раз.

pito211, ну да, забыл я выделить память в конструкторе по умолчанию, ну блин, взял бы да сказал- ты kravam забыл выделить память в конструкторе по умолчанию. Ты же понимаешь, что я просто забыл это сделать. Зачем же ногами топтать?

Насчёт инкапсуляции- а вот здесь ты попал пальцем в небо.
Итак, сокрытие данных
C++
1
matrix_[4][6];
куда уж больше скрывать.

И опять же, нравится тебе () вместо [][], я тебе слова не скажу. Я же не спрашивал никого- что лучше? Я сказал: возвращение в функцию безымянного объекта нужно для того-то и того-то. Всё!

Добавлено через 1 минуту
Maxwe11, не аргумент. Я маскирую мой код под классический синтаксис. ЧЯДНТ?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
27.06.2011, 20:01     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #44
kravam, мы с вами никак понять друг друга не можем. Мой вопрос: с какой целью каждый раз при вызове operator[] оборачивать указатель в объект nemo, если можно изначально хранить массив объектов nemo, и в operator[] просто возвращать соответствующий элемент этого массива. Проблемы исчезнут, поскольку эти new nemo в operator[] перенесутся в конструктор, а утечки исчезнут за счёт деструктора. Да, вы всегда упрощаете код, когда задаёте вопрос. В этом есть немало плюсов. Но иногда за таким мощным упрощением сути не видишь и всегда ищешь, как можно проще добиться подобного эффекта. Но вдруг проще нельзя, потому что реальная задача (а не абстрактный упрощённый пример) этого не допустит?

Не по теме:

И перестаньте уже срываться на всех подряд. Вам пытаются помочь, а вы это воспринимаете как жёсткую критику. Ну, написал вам один грубо, ну так остальные участники обсуждения тут причём?

kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
27.06.2011, 20:46  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #45
Да вы поймите, у меня одна проблема, она в моём незнании и она решается легко: как удалить этот объект:
C++
1
matrix_[4];
после использования
Так я понял, как. Создать его в функции и вернуть; так, а умный компилятор не будет создавать его в функции, а создаст в месте, куда он должен возвернуться и потом удалит не дожидаясь main, это там мне в ассемблерном листинге объяснили. Так что всё, проблема одна вполне рабочая, решилась.

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

А вот тут я посмотрел чему равен объект класса nemo
C++
1
 printf ("==  %d\n", sizeof (matrix<int>::nemo));
Тоже 4 байта.

То есть то на то на то и выходит, но я не умею сходу определять, что там занимает память а что нет:
C++
1
2
3
4
5
6
  class nemo;
  nemo& operator[](int nomer_stroki) {
   nemo* ne= new nemo [1];
   ne->k= (T*)(p[nomer_stroki]); 
   return *ne;
  };
Явно вижу nemo* 4 байта. НО ведь и всё остальное тоже сущности! Где они хранятся? Где-то же они есть! Ну вот я не могу определить более или менее правильно размер типа, поэтому он мне кажется большим, а на самом деле маленький.

Такая вот одна причина причина, по которой мне в голову не могло прийти создать nemo array [x]; Она может и глупая но других вроде нет. А так-то можно, да, щас я начинаю понимать, но будет наверное одинаково продуктивный код что мой что ваш.

Добавлено через 13 минут
А вот другая причина, повесомее
C++
1
2
matrix<int> y (6, 7);
y[2][4]= 99;
смотрите, у меня конструируется объект класса nemo 1(!) раз

А если ваш код такой же написать, то у вас создастся массив собъектов nemo.
silent_1991, сколько раз вызовется конструктор nemo? 6 объектов, 6 раз вызывается конструктор nemo... Эта причина повесомее будет...
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 20:51     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #46
C++
1
2
3
4
5
nemo operator[](int nomer_stroki) {
   nemo ne;
   ne.k= (T*)(p[nomer_stroki]); 
   return ne;
  };
вот так наверно должно быть


Цитата Сообщение от kravam Посмотреть сообщение
будет наверное одинаково продуктивный код что мой что ваш
доступ к элементу в твоём коде на порядок медленее конструкции с T **p и оператором(). А в классе silent1991, который с Row, каждый вектор хранит свою длинну, соответсвенно количество бесполезной занятой памяти растёт линейно.

Добавлено через 3 минуты
кароче T** и оператор() рулят
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
27.06.2011, 20:55  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #47
Исправления принимаются, pito211, как насчёт количества вызовов конструктора класса nemo? У меня он вызовется столько раз, сколько... э вызовется,
C++
1
matrix<int> y (6, 7);
тут например, ни разу.

у silent_1991 по количеству строк;

Добавлено через 2 минуты
Цитата Сообщение от pito211 Посмотреть сообщение
кароче T** и оператор() рулят
ты меня не путай.
T** p это вроде мой код;

а [][] я отдам предпочтение перед () и точка (синтаксис, знаешь ли), пусть последний даже быстрее.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 21:07     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #48
Цитата Сообщение от kravam Посмотреть сообщение
у silent_1991 по количеству строк;
там несколько другой смысл класса Row, Row!=nemo. Он инкапсулирует Row, а у тебя это просто обёртка. Чё сколько раз там вызывается я не считал, но думается его код напорядок лучше хотя бы тем что он понятнее в разы. Трюк с nemo в матрице вобще ни к месту. В ссылке которую дал silent_1991 ещё есть матрица с Т** только там оператор[] и его надо заменить на (), иначе нарушается инкапсуляция. Вот это будет оптимальный вариант скорее всего
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
27.06.2011, 21:08     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #49
kravam, вы по той ссылке, что я в 34 посте этой темы давал, ходили? Там два вариант кода. Один вариант - с дополнительным классом Row. Второй (под заголовком "Метод pito211") - с использованием T ** (только там класс не шаблонный, что правится в 30 секунд). Никаких конструкторов дополнительных, и [][] используется. Чем не подходит?

Добавлено через 1 минуту

Не по теме:

pito211, опередил))

kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
27.06.2011, 21:12  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #50
Пусть там будут комменты, тогда буду посмотреть. В том который метод pito211
В моём коде есть потому, что, в моём коде комменты есть всегда.

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
27.06.2011, 21:14     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #51
kravam, Не стоит писать комменты для очевидных вещей. Не понятно - книжку в зубы и вперед.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 21:19     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #52
коменты нужны для комментирования сложных участков кода. Там всё просто до безобразия. Рука не поднимается такой код загрязнять комментариями
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
27.06.2011, 21:19     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #53
kravam, омг, не уж то так всё сложно? Всё-таки вам это надо, не нам. Могли бы и разобраться...
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
 
// Шаблонный класс "Матрица"
template< typename T >
class Matrix
{
public:
    // Конструктор
    // rows - количество строк
    // cols - количество столбцов
    Matrix(size_t rows = 1, size_t cols = 1):
    m_rows(rows),             // Инициализируем количество строк
    m_cols(cols),             // Инициализирцем количество столбцов
    m_matrix(new T *[m_rows]) // Выделяем память под массив указателей
    {
        // Инициализируем каждый указатель массива отдельно выделенным массивом
        for (size_t i = 0; i < m_rows; ++i)
            m_matrix[i] = new T [m_cols];
    }
 
    // Деструктор
    ~Matrix()
    {
        // Удаляем каждый из массивов, на которые указывают элементы массива
        // указателей
        for (size_t i = 0; i < m_rows; ++i)
            delete [] m_matrix[i];
 
        // Удаляем массив указателей
        delete [] m_matrix;
    }
 
    // Оператор []
    T *operator[](size_t index)
    {
        // Возвращаем соответствующую строку матрицы
        return m_matrix[index];
    }
 
    // Константный оператор [] (аналогично неконстантному)
    const T *operator[](size_t index) const
    {
        return m_matrix[index];
    }
 
private:
    size_t m_rows; // Количество строк матрицы
    size_t m_cols; // Количество столбцов матрицы
    T **m_matrix;  // Сама матрица
};
 
int main()
{
    const size_t rows = 2;
    const size_t cols = 2;
 
    Matrix< double > m(rows, cols);
 
    for (size_t i = 0; i < rows; ++i)
        for (size_t j = 0; j < cols; ++j)
            m[i][j] = i + j;
 
    for (size_t i = 0; i < rows; ++i)
    {
        for (size_t j = 0; j < cols; ++j)
            std::cout << m[i][j] << "  ";
 
        std::cout << std::endl;
    }
 
    return 0;
}
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,268
27.06.2011, 23:39  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #54
Не стоит слова говорить- очевидных-неочевидных. Собеседников надо уважать по-любому.

Добавлено через 34 минуты
Да, ребята, я всё понял. Ну чё у меня опыта если нет, я перегрузил вчера два раза оператор [] и ошалел прямо от счастья, надо понимать. Казалось бы куда проще- и ведь знаю что адрес[индекс] даст значение, а глаз как замылился ровно. Ну да ладно, на ошибках учатся. Спасибо, я теперь закрепил эту херь, надо вот ещё сделать этот класс шаблонным, pito211, а можно я перегрузку оператора [][] у тебя позаимствую?

Добавлено через 27 минут
ВСя эта муть с классом nemo свелась к
C++
1
2
3
  T* operator[](int nomer_stroki) {
   return p[nomer_stroki];
  };
Добавлено через 1 час 17 минут
Зацените
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
 
// Шаблонный класс "Матрица"
template< typename T >
class Matrix
{
public:
    // Конструктор
    // rows - количество строк
    // cols - количество столбцов
    Matrix(size_t rows = 1, size_t cols = 1):
    m_rows(rows),             // Инициализируем количество строк
    m_cols(cols),             // Инициализирцем количество столбцов
    m_matrix(new T *[m_rows]) // Выделяем память под массив указателей
    {
        // Инициализируем каждый указатель массива отдельно выделенным массивом
        for (size_t i = 0; i < m_rows; ++i)
            m_matrix[i] = new T [m_cols];
    }
 
    // Деструктор
    ~Matrix()
    {
        // Удаляем каждый из массивов, на которые указывают элементы массива
        // указателей
        for (size_t i = 0; i < m_rows; ++i)
            delete [] m_matrix[i];
 
        // Удаляем массив указателей
        delete [] m_matrix;
    }
 
    //+++++++++++++++++Вот это++++++++++++++++++++
    operator T**() {return m_matrix;};
 
private:
    size_t m_rows; // Количество строк матрицы
    size_t m_cols; // Количество столбцов матрицы
    T **m_matrix;  // Сама матрица
};
 
int main()
{
    const size_t rows = 2;
    const size_t cols = 2;
 
    Matrix< double > m(rows, cols);
 
    for (size_t i = 0; i < rows; ++i)
        for (size_t j = 0; j < cols; ++j)
            m[i][j] = i + j;
 
    for (size_t i = 0; i < rows; ++i)
    {
        for (size_t j = 0; j < cols; ++j)
            std::cout << m[i][j] << "  ";
 
        std::cout << std::endl;
    }
     getchar ();
    return 0;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
27.06.2011, 23:46     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #55
kravam, Оригинально, но такой оператор не айс. Обычно пытаются запретить преобразование в указатель... А вы его явно делаете...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2011, 10:17     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант!
Еще ссылки по теме:

C++ Что будет с указателем после использования операции delete?
C++ Как подключить головной и ресурсный файлы к основной программе
C++ Зачем использовать delete в небольшой программе, если после закрытия память все равно освободится?

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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
28.06.2011, 10:17     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #56
kravam, чтобы совсем не нарушать инкапсуляцию, лучше делать с дополнительным объектом, как я показывал в самый первый раз. А в этом коде без нарушения инкапсуляции лучше делать так (правда, я уже понял, что вас такой вариант не устраивает):

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
 
template< typename T >
class Matrix
{
public:
    Matrix(size_t rows = 1, size_t cols = 1):
    m_rows(rows),
    m_cols(cols),
    m_matrix(new T *[m_rows])
    {
        for (size_t i = 0; i < m_rows; ++i)
            m_matrix[i] = new T [m_cols];
    }
 
    ~Matrix()
    {
        for (size_t i = 0; i < m_rows; ++i)
            delete [] m_matrix[i];
 
        delete [] m_matrix;
    }
 
    T &operator()(size_t v_index, size_t h_index)
    {
        return m_matrix[v_index][h_index];
    }
 
    const T &operator()(size_t v_index, size_t h_index) const
    {
        return m_matrix[v_index][h_index];
    }
 
private:
    size_t m_rows;
    size_t m_cols;
    T **m_matrix;
};
 
int main()
{
    const size_t rows = 2;
    const size_t cols = 2;
 
    Matrix< double > m(rows, cols);
 
    for (size_t i = 0; i < rows; ++i)
        for (size_t j = 0; j < cols; ++j)
            m(i, j) = i + j;
 
    for (size_t i = 0; i < rows; ++i)
    {
        for (size_t j = 0; j < cols; ++j)
            std::cout << m(i, j) << "  ";
 
        std::cout << std::endl;
    }
 
    return 0;
}
Yandex
Объявления
28.06.2011, 10:17     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант!
Ответ Создать тему
Опции темы

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