Destructor vector <vector <T>>. C++
namespace atsan
{
typedef unsigned int size_type;
template <class T> class vector : public std::vector <T>
{
private:
typedef std::vector <T> vector_stl;
public:
explicit vector() : vector_stl() {};
explicit vector(size_type n, const T& value = T()) : vector_stl(n, value) {};
vector (const vector& x) : vector_stl(x) {};
~vector() {};
};
template <class T> class matrix
{
private:
typedef atsan::vector <T> vector_my;
typedef std::vector <vector_my> vector_stl;
vector_stl general;
public:
explicit matrix() {};
explicit matrix(size_type m, size_type n, const T& value = T());
matrix(const matrix& x);
~matrix();
vector_my& operator[] (size_type m) {return general[m];}
vector_my operator[](size_type m) const {return general[m];}
size_type size_line() const {return general.size();}
};
template <class T> matrix <T> :: matrix(size_type m, size_type n, const T& value)
{
vector_my temp(n, value);
general.resize(m, temp);
}
template <class T> matrix <T> :: matrix(const matrix& x)
{
general.resize(x.size_line());
for (size_type i = 0; i < x.size_line(); i++)
general = x;
}
template <class T> matrix <T> :: ~matrix()
{
for (size_type i = 0; i < size_line(); i++)
general.~vector_my();
}
}
general.~vector_my();
на
delete &general;
Builder скушал и был вполне доволен таким блюдом. В общем такое решение вроде имеет право на жизнь(я в смысле что дополнительных проблем из-за такой замены на мой взгляд возникнуть не должно).
З.Ы.: Dev тоже понравилось: :D
Множество глупостей:
Не рекомендую использовать в .h
От классов STL не рекомендуется наследоваться.
Зачем вообще этот класс?
Совершенно не нужные "телодвижения".
typedef std::vector <vector_my> vector_stl;
vector_stl general;
Вот это можно было значительно проще сделать:
{
vector_my temp(n, value);
general.resize(m, temp);
}
а именно вот так:
: general(m, std::vector<T>(n, value))
{
}
Абсолютно ненужный код:
{
general.resize(x.size_line());
for (size_type i = 0; i < x.size_line(); i++)
general = x;
}
А теперь самое главное. Деструктор будет выглядеть так:
{
}
Гы... :D
P.S. А ещё ОЧЕНЬ полезно пользоваться поиском. Например, чтоб посмотреть мой вчерашний пост: http://forum.codenet.ru/showthread.php?t=43710
Не рекомендую использовать в .h
Это был еще не *.h, как закончу перемещу в *.h
Задания звучало примерно так. Создать классовый тип вектор - одномерный численный массив динамического типа с изменяемыми размерами. Создать классовый тип матрица...
Все ф-ии я убрал.
Совершенно не нужные "телодвижения".
typedef std::vector <vector_my> vector_stl;
vector_stl general;
Мне приятней было писать такие имена :)
{
vector_my temp(n, value);
general.resize(m, temp);
}
а именно вот так:
: general(m, std::vector<T>(n, value))
{
}
Будем знать.
{
general.resize(x.size_line());
for (size_type i = 0; i < x.size_line(); i++)
general = x;
}
В том же задании написано: создать конструктор копирования.
{
}
Гы... :D
Только память он не оччищает. Если б было настолько просто не спрашивал бы =)
for (size_type i = 0; i < size_line(); i++)
delete &general;
Компилятор и на тот вариант не ругался, но при запуске дестрцуктора ошибка появляется.
В том же задании написано: создать конструктор копирования.
Тогда так:
: general(x.general)
{
}
Только память он не оччищает. Если б было настолько просто не спрашивал бы =)
А с чего ты взял, что память не очищается?
Именно так просто!
Давай, ты попробуешь обосновать, что память не освобождается.
И если в процессе обоснования сам не поймешь, что не прав, тогда это покажу тебе я. Ок?
Подсказка: почему в твоем классе vector такой простой деструктор?
А с чего ты взял, что память не очищается?
Именно так просто!
Давай, ты попробуешь обосновать, что память не освобождается.
И если в процессе обоснования сам не поймешь, что не прав, тогда это покажу тебе я. Ок?
написал небольшой тест для проверки.
1)Обьем памяти смотрел в Process Explorer
atsan::vector <float> a(1000, 100.34); //тут память приложения увеличивается
getch();
a.~vector(); //память возвращатся в исходные значения
2)atsan::matrix <float> a(1000, 1000, 100.34); //тут память приложения увеличивается
getch();
a.~matrix(); //память НЕ возвращатся в исходные значения
1)Обьем памяти смотрел в Process Explorer
atsan::vector <float> a(1000, 100.34); //тут память приложения увеличивается
getch();
a.~vector(); //память возвращатся в исходные значения
2)atsan::matrix <float> a(1000, 1000, 100.34); //тут память приложения увеличивается
getch();
a.~matrix(); //память НЕ возвращатся в исходные значения
Как проверяешь, что память "возвращается в исходные значения"?
А кто тебя так учил деструкторы вызывать? Не делай так!
Кроме того, деструктор не освобождает память объекта, а лишь разрушает объект.
Память освобождается другими функциями.
Но это к нашей теме отношения не имеет.
Скажи, почему ты не реализовал в своем классе vector деструктор, что-то типа такого:
{
for (size_type i = 0; i < size(); i++)
(*this).~T();
}
не кажется ли тебе это абсурдным?
Как проверяешь, что память "возвращается в исходные значения"?
В колонке "используемая память".
Скажи, почему ты не реализовал в своем классе деструктор, что-то типа такого:
{
for (size_type i = 0; i < size(); i++)
(*this).~T();
}
не кажется ли тебе это абсурдным?
Эта и похоже на бред, надо больше спать, чтоб голова была светлей =)
Эта и похоже на бред, надо больше спать, чтоб голова была светлей =)
Значит это бред:
{
for (size_type i = 0; i < size(); i++)
(*this).~T();
}
а это нет?
{
for (size_type i = 0; i < size_line(); i++)
general.~vector_my();
}
хотя оба кода выполняют одно и тоже.
А компьютер ты случайно выключаешь не путем выдергивания вилки из розетки. Это правильный способ выключения?
А теперь как правильно проверить:
#include <iostream>
struct Test
{
Test() {
std::cout << "Test() counter=" << ++counter << std::endl;
}
Test(const Test&) {
std::cout << "Test() counter=" << ++counter << std::endl;
}
~Test() {
std::cout << "~Test() counter=" << counter-- << std::endl;
}
static int counter;
};
int Test::counter = 0;
int main()
{
{
std::vector<Test> array(5);
}
std::cout << "result counter=" << Test::counter << std::endl;
return 0;
}
Логично, что вызовов деструкторов должно быть столько же, сколько и вызовов конструкторов, т.е. счетчик должен быть равен в конечном счете нулю.
Здесь вопросов не возникает? Тебя не удивляет, что все созданные экземпляры класса Test были уничтожены без твоего участия?
Скажи, если я переименую свою переменную array, например в general, от этого что-нибудь изменится? Экземпляры Test не уничтожаться? Деструкторов будет меньше, чем кончтрукторов?
Так чем же твой класс matrix такой особенный, что в нем что-то нао удалять самому?
А не проверить ли его с помощью класса Test ?