Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.02.2013, 14:32   #1
abc7
 
Регистрация: 20.02.2013
Сообщений: 6
По умолчанию Выделение и освобождение памяти в конструкторе и деструкторе

Помогите задать конструктор выделяющий память для переменных x1,y1,z1,x2,y2,z2 и деструктор ее освобождающий.
Код:
#include <iostream>
#include <math.h>
using namespace std;
class vectors
{
public:float x1,y1,z1;
       float x2,y2,z2;
       float a1,b1,c1;
	   float a2,b2,c2;
	   float c,d1,d2,m;
    float vvod1()
	{
	cout<<"Введите координаты первого вектора\n";
	cin>>x1;cin>>y1;cin>>z1;
	return 0;
	}
	float vvod2()
	{
	cout<<"Введите координаты второго вектора\n";
	cin>>x2;cin>>y2;cin>>z2;
	return 0;
	}
    float sum(float p1,float p2,float p3)
	{
	a1=x1+p1;b1=y1+p2;c1=z1+p3;
	cout<<"Сумма векторов\n"<<a1<<" "<<b1<<" "<<c1<<"\n";
	return 0;
	}
	float raz(float p1,float p2,float p3)
	{
	a2=x1-p1;b2=y1-p2;c2=z1-p3;
	cout<<"Разность векторов\n"<<a2<<" "<<b2<<" "<<c2<<"\n";
	return 0;
	}
    float dlina1()
	{
	d1=sqrt(x1*x1+y1*y1+z1*z1);
	cout<<"Длина первого вектора\n"<<d1<<"\n";
    return d1;
	}
    float dlina2()
	{
	d2=sqrt(x2*x2+y2*y2+z2*z2);
	cout<<"Длина второго\n"<<d2<<"\n";
    return d2;
	}
	float cos(float p1,float p2,float p3)
	{
    c=(x1*p1+y1*p2+z1*p3)/(sqrt(x1*x1+y1*y1+z1*z1)*sqrt(p1*p1+p2*p2+p3*p3));
	cout<<"Косинус между векторами\n"<<c<<"\n";
	return c;
	}
    float scal(float p1,float p2,float p3)
	{
	m=sqrt(x1*x1+y1*y1+z1*z1)*sqrt(p1*p1+p2*p2+p3*p3)*c;
	cout<<"Скалярное произведение векторов\n"<<m<<"\n";
	return m;
	}
    float u1(){return x1;}float u2(){return y1;}float u3(){return z1;}
	float t1(){return x2;}float t2(){return y2;}float t3(){return z2;}
};
int main()
{
setlocale(LC_ALL,"Russian");
vectors v1,v2;
v1.vvod1();v2.vvod2();
v1.sum(v2.t1(),v2.t2(),v2.t3());v1.raz(v2.t1(),v2.t2(),v2.t3());
v1.dlina1();v2.dlina2();
v1.cos(v2.t1(),v2.t2(),v2.t3());v1.scal(v2.t1(),v2.t2(),v2.t3());
system ("PAUSE");
return 0;
}
abc7 вне форума Ответить с цитированием
Старый 20.02.2013, 15:07   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

1) Память для членов примитивных типов (float относится к таковым) выделяется как часть памяти, выделяемой под объект (т.е. переменная v1 имеет размер не менее 16*sizeof(float)). Соответственно, код для выделения/освобождения этой памяти в приведённом примере генерируется компилятором автоматически.

2) Код кошмарен. Переменные-члены не должны иметь уровень доступа public, если только для этого нет очень веских оснований. Методы sum и raz вводят в заблуждение, возвращая значения, не имеющие ничего общего с "суммой" или "разностью". Также они меняют состояние объекта в высшей степени неочевидным образом. Основная программа запутывает ещё больше: класс vectors, по всей видимости, описывает пару векторов, в программе объявляются две пары, но каждая из них остаётся в не полностью инициализированном состоянии. Отдельно путаницы добавляют разночтения в индексах членов (x1, x2, x3 нет, но есть z2) и аксессоров (u1, u2, u3).
Abstraction вне форума Ответить с цитированием
Старый 20.02.2013, 16:21   #3
abc7
 
Регистрация: 20.02.2013
Сообщений: 6
По умолчанию

Цитата:
код для выделения/освобождения этой памяти в приведённом примере генерируется компилятором автоматически.
То есть выделять память под эти переменные нет смысла? Тогда какой к программе можно прикрутить конструктор и деструктор?
По поводу кошмарности кода. Это моя первая программа с использованием классов так что как сделать по-другому я просто не знаю.

Последний раз редактировалось abc7; 20.02.2013 в 16:40.
abc7 вне форума Ответить с цитированием
Старый 20.02.2013, 16:21   #4
intmain
Играюсь с Python
Форумчанин
 
Аватар для intmain
 
Регистрация: 12.12.2012
Сообщений: 340
По умолчанию

Цитата:
Переменные-члены не должны иметь уровень доступа public
Это почему? Удобнее обращаться непосредственно к переменной, а не городить для нее set/get методы. имхо.

Цитата:
Код кошмарен
Соглашусь с тобой. Он действительно кошмарен особенно это форматирование отступов, и транслит в именовании переменных. тихий ужс просто. Хотя я сам не лучше пишу, лол.
Что ел то - в долг, что жил то - зря.
Для избранных. ))
Секретные разработки
intmain вне форума Ответить с цитированием
Старый 20.02.2013, 16:58   #5
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Это почему? Удобнее обращаться непосредственно к переменной, а не городить для нее set/get методы. имхо.
Я в курсе, что ХО означает "хрен оспоришь", но всё же...
1) Уничтожена возможность переименовать или убрать переменную, модифицируя только код класса. К примеру, класс хранит длины сторон прямоугольника и его площадь - если мы сделали площадь переменной, а потом решили, что выгоднее её только вычислять при обращениях, геттер позволит провести такое изменение, а прямой доступ нет (потому что перестанет работать код, обращавшийся к этой переменной).
2) Уничтожена возможность гарантировать инварианты класса. Опять же, если у нас есть класс прямоугольника и три переменных - длина, ширина, площадь, - мы можем гарантировать в коде класса, что всегда площадь==длина*ширина. А если переменные может поменять любой хрен с горы, такой гарантии дать уже нельзя.
3) В случае управляемых ресурсов повышается опасность того, что ссылка на ресурс переживёт управляющий объект. Если наш объект получил файловый дескриптор и не дал возможности его "утащить" - с уничтожением объекта возможность доступа к данному дескриптору гарантированно утеряна, поэтому его можно освободить. А если это открытый член, то какой-нибудь дятел скопирует себе дескриптор, попытается использовать его после уничтожения объекта... и будет упс.
4) Нарушается инкапсуляция, сокрытие информации. Данные-члены обычно содержат информацию о том, как именно реализован объект. Если они закрыты, эту информацию следует держать в голове только во время работы над кодом класса. Если они открыты, эта информация актуальна в любой точке, где используется класс. Чем больше факторов надо удерживать в голове при написании кода, тем тяжелее его писать, легче совершить ошибку и тяжелее понять получившийся код впоследствии.

Цитата:
Тогда какой к программе можно прикрутить конструктор и деструктор?
Конструктор и деструктор "прикручиваются" к классу. Нетривиальные (не генерируемые автоматически) деструкторы требуются только тогда, когда прекращение существования объекта означает необходимость проделать какие-то действия. В простейшем случае - освободить динамически выделенную память. Конструктор можно составить почти всегда - как минимум, явно инициализировать все данные-члены класса начальными значениями.
Abstraction вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
выделение памяти и ее освобождение Артэс Общие вопросы C/C++ 15 03.11.2012 14:22
Динамическое Выделение Памяти В Конструкторе Класса D-Vampire Общие вопросы C/C++ 5 20.12.2011 00:34
Расхождение адресов в конструкторе и деструкторе _-Re@l-_ Общие вопросы C/C++ 13 13.08.2011 20:31
Полиморфизм и выделение (освобождение) памяти Scogan Общие вопросы C/C++ 9 13.04.2009 07:57
Освобождение памяти AlexandrSid Общие вопросы Delphi 3 02.02.2009 13:45