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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 5.00
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
#1

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

26.06.2011, 22:40. Просмотров 2484. Ответов 55
Метки нет (Все метки)

Собсно


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++ Что будет с указателем после использования операции delete?
C++ Беда с оператором DELETE
C++ Зачем использовать delete в небольшой программе, если после закрытия память все равно освободится?
C++ Прочитать никнейм из файла и после использования - удалить
C++ Не создаётся объект класса
C++ Как подключить головной и ресурсный файлы к основной программе
Не создаётся объект string на ровном месте! Почему? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 17:20     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #31
странные у тебя запросы(по поводу самого первого листинга). Думаю в полевых условиях такие вещи впринципе городить не придётся
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
27.06.2011, 17:36  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #32
Код сырой, можешь сразу посмотреть main
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <typeinfo>
#include <time.h>
 
template <class T>
class matrix {
 public:
 
  //Кнструтор по умолчанию создаёт матрицу из 2-х строк и одного столбца; ничем не инициализирует
  matrix () {srand (time(0));kol_vo_strok= 2; kol_vo_stolb= 1;};        
 
  //Конструктор просто создаёт матрицу, выделяет место под строи и столбцы, но не инициализирует их
  //В деструкторе, понятно, эта память освободится
  matrix (int x, int y):kol_vo_strok(x), kol_vo_stolb(y) {
   srand (time(0));
   p= new T* [x];
   for (int i= 0; i< x; i++) {
    p[i]= new T [y];
   }
  };        
 
 
  //А это деструктор, освобождает на хер всю занятую память
  ~matrix () {
   for (int i= 0; i< kol_vo_strok; i++)
    delete [] p[i];
    delete [] p;
   };        
 
  //Инициализация матрицы рандомно значениями от x до y влючительно
  //если значения типа double, то тоже будет всё нормально, после запятой будет два знака
  void init_rand (int x, int y) {
   double temp;
   for (int i= 0; i< get_kol_vo_strok(); i++) {
    for (int j = 0; j< get_kol_vo_stolb(); j++) {
     p[i][j]= rand()%(y- x+ 1)+ x;
     if (typeid(p[i][j])== typeid (temp)) {
      if (p[i][j]!= y) {
       p[i][j]+= (T)rand()/(RAND_MAX+1);;
      }
     }
    }
   }
  }
 
 
  //Это вот вывод матрицы
  void vivod () {
   double temp;
   for (int i= 0; i< get_kol_vo_strok(); i++) {
    for (int j = 0; j< get_kol_vo_stolb(); j++) {
     if (typeid(p[i][j])== typeid (temp))
      printf ("%.2f ", (double)p[i][j]);  
     else
      printf ("%3d ", p[i][j]);  
    }
    printf ("\n");
   }
  }
 
 
 
  //Устанавливает количество строк
  void set_kol_vo_strok (T x) {kol_vo_strok= x;};
  //... и количество столбцов
  void set_kol_vo_stolb (T x) {kol_vo_stolb= x;}
 
 
  //Возвращаает количество строк
  int get_kol_vo_strok () {return kol_vo_strok;};
  //... и количество столбцов
  int get_kol_vo_stolb () {return kol_vo_stolb;}
 
  
  //Перегрузка операторов
  //Это перегрузка оператора []; работает пока но этого мало, надо чтобы была перегрузка [][]  
 
  class nemo {
   public:
    T* k;   
    T& operator[](int nomer_stolbtsa) {
     return (k[nomer_stolbtsa]);
    };
  };
  
  //А вот из этой функции возвращается объект класса nemo. 
  //ПОка возвращается ссыль, но я буду переделывать, чтобы возвращался объект.
  nemo& operator[](int nomer_stroki) {
   nemo* ne= new nemo [1];
   ne->k= (T*)(p[nomer_stroki]); 
   return *ne;
  };
  
 
 
 
 private:
 
  //Количество строк, количество столбцов
  int kol_vo_strok;         
  int kol_vo_stolb;         
 
 
// public:
  //Динамический мссив из указателей на указатели на T
  T**p;
 
 
};
 
 
int main () {
 
 matrix<int> y (6, 7);
 y.init_rand (1, 100);
 y.vivod();
 printf ("\n");  
 
 //Благодаря моей дури, эта херь корректна:
 printf ("%d\n", y[3][4]);  
 y[3][4]= 99;
 
 y.vivod();
 printf ("\n");  
 
 getchar (); 
 
}
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.06.2011, 17:41     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #33
Цитата Сообщение от kravam Посмотреть сообщение
надо чтобы была перегрузка [][]
для этого делается класс вектор(в котором перегружен оператор []), на базе которого делается класс матрицы(в котором тоже перегружен оператор [])
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.06.2011, 17:46     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #34
kravam, есть какая-то магия, какие-то дикие запросы на то, чтобы в классе matrix хранить именно двойной указатель, а не массив объектов nemo? Потому что пока это выглядит как извращение и хреновое проектирование. Храни вы массив строк, то вы бы просто из operator[] матрицы возвращали ссылку на строку, а из operator[] строки возвращали элемент строки. Недавно эта тема разжёвывалась же.
Вот.
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 17:52     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #35
зачем интересно нужен конструктор по умолчанию, если он не рабочий спрячь его в приват

Добавлено через 4 минуты
лучше перегружать оператор(), а то так ты получается даёшь пользователю поиграться с указателями matrix[]. В терминологии не силён но помоему тут нарушается инкапсуляция или что-то типо того. Но точно что-то из принципов ООП нарушается

double temp; в 35 строке неиспользуемая переменная, точнее она только в typeid используется, короче выкинуть её

и вобще это всё жуткий быдлокод, весь обплевался пока читал
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
27.06.2011, 18:46  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #36
Советов я ничьих не спрашивал. Это кстати. Всё, что вы сказали- лишнее, могли бы не говорить. Я слишком ответственно отношусь к любому своему код, чтобы не отвечать за каждую строчку

Специально для тех, кто не увидел: это класс шаблонный, предполагается матрица из ЛЮБЫХ авторских переменных

C++
1
2
3
struct tip {
 //куча полей
}
Именно поэтому
C++
1
T** p;
А иначе, silent_1991, ума хранить массив строк у меня хватило бы. Скажи ещё, что не веришь мне?

И да, для каждого авторского класса мне придётся переопределять функции, например vivod и не надо мне об этом говорить.

"зачем интересно нужен конструктор по умолчанию, если он не рабочий спрячь его в приват"
Он рабочий и он нужен. Как нужен конструктор пустой строки или пустого вектора, ОК?

"лучше перегружать оператор(), а то так ты получается даёшь пользователю поиграться с указателями matrix[]" Это ты что предлагаешь?
matrix () (); matrix () [] или matrix [] ()?

Конгениально, чё могу сказать

"В терминологии не силён но помоему тут нарушается инкапсуляция или что-то типо того. Но точно что-то из принципов ООП нарушается"" тьфу

"и вобще это всё жуткий быдлокод, весь обплевался пока читал " тебя никто об этом не просил, надо было- посмотрел бы только то, что я сказал посмотреть, сказано было- код сырой.
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
27.06.2011, 18:49     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #37
Хочется только немного слов сказать в защиту прокси-объектов. Никакие принципы ООП они при правильной реализации не нарушают. И иногда это единственный из удобных способов получить желаемое. В данном случае не единственный, но вполне возможный.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.06.2011, 18:50     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #38
kravam, во-первых, я не давал повода так со мной разговаривать. Во-вторых, про строки (string или char*) речи не шло. И что, что класс шаблонный? Гляньте код по ссылке, сделайте классы Row и Matrix шаблонными и живите счастливо.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
27.06.2011, 18:51  [ТС]     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #39
В данном случае, например.
И вообще скропайте перегрузку оператора [][] по-другому, предполагая, что элемент матрицы- элемент любого типа, тогда и будете базлать. Пока же всем вашим замечаниям в базарный день красная цена копейка.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.06.2011, 18:55     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #40
Цитата Сообщение от 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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
 
template< typename T >
class Row
{
public:
    Row(size_t size = 1):
    m_size(size),
    m_row(new T [m_size])
    {
        for (size_t i = 0; i < m_size; ++i)
            m_row[i] = 0.0;
    }
 
    Row(const Row &source):
    m_size(source.m_size),
    m_row(new T [m_size])
    {
        for (size_t i = 0; i < m_size; ++i)
            m_row[i] = source.m_row[i];
    }
 
    ~Row()
    {
        delete [] m_row;
    }
 
    void resize(size_t new_size)
    {
        double *new_row = new T [new_size];
 
        for (size_t i = 0; i < m_size; ++i)
            new_row[i] = m_row[i];
 
        for (size_t i = m_size; i < new_size; ++i)
            new_row[i] = 0.0;
        
        delete [] m_row;
 
        m_row = new_row;
        m_size = new_size;
    }
 
    T &operator[](size_t index)
    {
        return m_row[index];
    }
 
    const T &operator[](size_t index) const
    {
        return m_row[index];
    }
 
private:
    size_t m_size;
    T *m_row;
};
 
template< typename T >
class Matrix
{
public:
    Matrix(size_t rows = 1, size_t cols = 1):
    m_rows(rows),
    m_matrix(new Row< T > [m_rows])
    {
        for (size_t i = 0; i < m_rows; ++i)
            m_matrix[i].resize(cols);
    }
 
    ~Matrix()
    {
        delete [] m_matrix;
    }
 
    Row< T > &operator[](size_t index)
    {
        return m_matrix[index];
    }
 
    const Row< T > &operator[](size_t index)const
    {
        return m_matrix[index];
    }
 
private:
    size_t m_rows;
    Row< 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;
}
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
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.06.2011, 19:50     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #42
Цитата Сообщение от pito211 Посмотреть сообщение
matrix(x, y);
не знаю насколько это гениально
в бусте именно так)
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
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
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.06.2011, 20:01     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! #44
kravam, мы с вами никак понять друг друга не можем. Мой вопрос: с какой целью каждый раз при вызове operator[] оборачивать указатель в объект nemo, если можно изначально хранить массив объектов nemo, и в operator[] просто возвращать соответствующий элемент этого массива. Проблемы исчезнут, поскольку эти new nemo в operator[] перенесутся в конструктор, а утечки исчезнут за счёт деструктора. Да, вы всегда упрощаете код, когда задаёте вопрос. В этом есть немало плюсов. Но иногда за таким мощным упрощением сути не видишь и всегда ищешь, как можно проще добиться подобного эффекта. Но вдруг проще нельзя, потому что реальная задача (а не абстрактный упрощённый пример) этого не допустит?

Не по теме:

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

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2011, 20:46     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант!
Еще ссылки по теме:
C++ Передача массива вызывающей функции
C++ Почему при инициализации строки, сначала создаётся пустой объект?
C++ Почему два раза создаётся объект с ОДНИМ И ТЕМ ЖЕ ИМЕНЕМ?
Ключевое слово const после декларации функции в классе C++
C++ Объект удаляется до возвращения его из функции

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

Или воспользуйтесь поиском по форуму:
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
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... Эта причина повесомее будет...
Yandex
Объявления
27.06.2011, 20:46     в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант!
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru