Проблема с композицией классов

Автор: rezistor Дата: 05.11.2007 11:37 Привет всем! Я недавно стал изучать С++ и столкнулся с такой проблемой: есть два класса, в торой входит, как часть первого. Как мне сделать, чтобы этот второй мог получать какое-то значение для конструктора из первого?
ЗЫ: Например, у меня есть класс граф, а в него входит класс динамическая матрица (я попытался сделать матрицу универсальной и включил в нее метод заполнения из файла). Хочется, чтобы она сразу и конструировалась из файла. Т.е. чтобы я из main передавал графу имя файла, а он это имя матрице для конструкстора.
ЗЫЫ: Я пробовал вот такое: Graph g(fileName); Но, оно работает только, когда я из мейн передаю. Если я в классе такое делаю, то получаю error: 'y' is not a type. y - это переменная, которую я завел в классе, чтобы через конструктор главного класса передать ей значение, а затем вызвать в подчиненном классе DynMatrice M(y);.
Спасибо!
Re: Проблема с композицией классов 05.11.2007 14:10Bircoph Ну и создайте экземляр матрицы в конструкторе графа,
передав нужный параметр.

> ЗЫЫ: ...

В этом бреде никто ничего не поймёт. Код нужно показывать.

Вот пример решения вашей проблемы:
A.h:
---
#include "B.h"

class A {
public:
A(int x) { matr = new B(x); }
~A() { delete matr; }
B* matr;
};
---
B.h:
---
#include <stdio.h>

class B {
public:
B(int x) { _x=x; }
void out() { printf("%i ",_x); }
private:
int _x;
};
---
main.cpp:
---
#include "A.h"

int main() {
A* test = new A(5);
test->matr->out();
delete test;
}
---
Re: Проблема с композицией классов 06.11.2007 17:19rezistor Большое СПАСИБО! Теперь разобрался Улыбка
Re: Проблема с композицией классов 04.02.2008 19:30kramer Bircoph, а разве нельзя так:
---
#include "B.h"

class A {
public:
A(int x): matr(x) {}
~A() {}
B matr;
};
---

А то не понятен смысл динамического выделения памяти...
Re: Проблема с композицией классов 04.02.2008 19:39Bircoph Можно. Но при работе с классами часто используют именно
динамическое распределение памяти, в т.ч. и я придерживаюсь
такого стиля.

Когда у вас есть указатель на объект, им гораздо удобнее
манипулировать, возвращать и т.п.; конечно, можно исползовать
ссылки на объект, но мне такой подход не по душе, да и не
всегда это целесообразно.
Re: Проблема с композицией классов 04.02.2008 20:04kramer Динамическая память, ИХМО, тоже не всегда целесообразна. К тому же она медленнее работает. Просто было странно видеть динамически выделенные объекты конкретно в данном контексте. Я так делал, если имел дело с полиморфизмом...

Но в чём вы правы - всё равно, динамически выделяется память, статически - главное чтобы прога работала.
Re: Проблема с композицией классов 05.02.2008 13:25Bircoph > Динамическая память, ИХМО, тоже не всегда целесообразна.

В конкретно приведённой мной программе -- да, безусловно
нецелесообразна. Но ведь речь идёт об использовании
подобного подхода в больших, более серьёзных программах,
не так ли?

А там уже без указателей не обойтись никак. Вот поэтому я
и решил в примере показать общий подход.
Re: Проблема с композицией классов 05.02.2008 14:05kramer Ну я опять же не думаю, что в больших и серьёзных программах необходимо использовать **только** динамическое выделение памяти, так что знать то что я показал тоже не помешает.

И насколько я понимаю Буча, доступ к полям класса вне методов класса не является желательным при ООП.
Re: Проблема с композицией классов 05.02.2008 16:55Bircoph > И насколько я понимаю Буча, доступ к полям класса вне
> методов класса не является желательным при ООП.

На такой случай напишате Set:hot:) и Get:hot:) функции. Но
целесообразность этого спорна, поскольку с помощью Set/Get
вы проделываете то же самое, т.о. Set/Get только усложняют
код. Всё зависит от предпочитаемого стиля программирования.
Источник: Стенли, Липман, соавторы стандарта C++ 2001.

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

Необходимость использования такой сложной структуры данных
как класс, в случае необходимости только статического
размещения данных, сомнительна.

Например, создание массива: конечно, можно создать массив
статически, но в реальности точное количество и параметры
входных данных известны только в очень маленьких и очень
узконаправленных программах. Обычно, там С++ не нужен вообще
и хватает нормального, шустрого С.
Re: Проблема с композицией классов 06.02.2008 13:20kramer Про только статическое выделени я тоже не говорю. Я говорю про использования и того и другого. Согласитесь, что у класса могут быть свойства, для которых динамическое выделение памяти не нужно. Приведу замену Set-Get функциям. В языке Object Pascal для этого существует property, а в С++ для получения того же эффекта нужно сделать чуть больше. Зачем это нужно? Дело в том, что если кто-то извне меняет непосредственно поле класса, сам объект класса об этом не знает, и соответсвенно не может предпринять соответсвующих действий (в вашем примере можно изменить значение matr и разрушить работу класса A), к тому же если поле класса как-то изменится, то придётся переписывать весь код, который имел доступ к этому полю. Ссылка: Ален Голуб. "Правила програмирования на С и С++". Пример написан грубовато и схематично, но суть ясна. Скомпилировался.

---
#include <iostream.h>

class window
{
class winh;
friend class window::winh; //для того, чтобы winh мог вызвать функцию sizes_changes
int sizes_changes()
{
cout << "размеры онка изменились" << endl;
// код по перерисовке окна и т. п.
}
class winh
{
int h;
window *owner;
public:
winh(int h1, window *ow): h(h1), owner(ow)
{}

winh &operator=(int h1)
{
h = h1;
owner->sizes_changes();
return *this;
}

operator int()
{
return h;
}
} h;
public:
window(int h1): h(h1, this)
{}

winh &height()
{
return h;
}
};

int main()
{
window w(12);
w.height() = 22;
return 0;
}
---

И про массив: внутри класса "Массив" память под элементы, несомненно, должна выделяться динамически, но сам объект этого класса можно содать и статически (или считаете, что вам может понадобиться неопределённое количество массивов?). В конце концов, указатель, который Вы используете для адресации объекта, созданного new - всё таки статический

Хотя впринципе, у нас спор не о чём, поскольку важен только итог - работающая и легко сопровождаемая прога.
RSS-материал