![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Приветствую всех.
Есть такой, упрощённый, случай:
Как создать наиболее рациональную реализацию setParams? Может есть паттерны или средства метапрограммирования(из того же boost'a)? Т.е. смысл в том, чтобы не завязываться на конкретном типе объекта наследника, а работать с данными-членами более гибко. Допустим по их именам(перечисление, задание, считывание...). Это сообщение отредактировал(а) W4FhLF - 13.3.2009, 19:06 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
т.е. setParams должен понять какой ему тип передали и задать соответствующие параметры???
а если написать виртуальную функцию, Body сделать абстрактным и вызывать его? Или еще проще, устанавливать параметры в конструкторе конкретного обьекта.. Задача немного неясна, что именно должна делать фунцкяи setParams ?? |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Заюзай enum в Body.
-------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Это всё немного не то. Представь, что у нас 15 наследников Body и у каждого свой набор параметров. Допустим теперь, что в функции setParams тебе необходимо получить от пользователя необходимый набор параметров для переданного объекта body(ну в случае сферы ты печатаешь в консоли Radius и ждёшь ввода, в случае Cone печатаешь Radius, потом, после ввода радиуса, печатаешь Height и т.д.). Каковы твои действия? andrew_121, не понял. Это сообщение отредактировал(а) W4FhLF - 13.3.2009, 19:44 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
если кол-во операций стабильно, но не стабильна иерархия (неизвестно конечное кол-во типов), то лучше просто использовать виртуальные функции
если ж наоборот иерархия классов постоянна(все конечные типы заранее известны), а общий интерфейс требует легкого расширения то смотрите паттерн визитор/двойная диспетчеризация. Это сообщение отредактировал(а) mes - 13.3.2009, 20:02 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот немного с форума об этом:
http://forum.vingrad.ru/index.php?showtopic=234230 http://forum.vingrad.ru/index.php?showtopic=235416 Это сообщение отредактировал(а) mes - 15.3.2009, 15:47 |
|||
|
||||
| AnLun |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 3.1.2008 Репутация: нет Всего: нет |
W4FhLF, а чем так плохо? |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
AnLun, что именно?
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
думаю что никак, так-как не понятно, что должна делать ф-я setParams, какие параметры(причем одни и те-же) передавать объектам разных типов... если нужно работать с геометрией, то я бы подумал о том, что-бы сделать вирт. ф-ю отвечающую за преобразования координат, которая в качестве параметра принимала-бы матрицу, на этой основе можно сделать любые преобразования, повороты, смещения и т.д.
Это сообщение отредактировал(а) Lazin - 20.3.2009, 11:52 |
|||
|
||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
а откуда setParams(Body*) возьмет значения параметров если они ей не передаются?
|
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот набросал условный пример работы :
Это сообщение отредактировал(а) mes - 20.3.2009, 12:44 |
||||
|
|||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
setParams(Body*) и Body::setParams() это одно и тоже, только 2е писать приятнее
|
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
тогда, как сказал mes, можно использовать либо паттерн visitor, либо обычную виртуальную ф-ю, но есть один ньюанс наиболее правильный ОО дизайн в этом случае, не строить огромную иерархию классов, состоящих их одних и тех-же элементов, а использовать композицию, то-есть выделить набор базовых примитивов (например point, angle, length) и создавать более сложные объекты на основе примитивных (например point, line(point, point), curve(point, point, point, point), rect(point, point, point, point), circle(point, length) etc) и создать механизм для поучения набора примитивных объектов из которых состоит более сложный объект в этом случае, можно будет придумать generic версию ф-ии setParams например, у нас есть набор объектов: Line, Circle, Rect нам нужно полиморфно с ними работать, сначала мы получаем первый объект Body(Line), и получаем список его параметров { "Begin":point, "End":point } и выводим на экран просьбу ввести сначала Begin, а затем End. Потом берем следующий объект Body(Circle) - {"Radius":length, "Center Coord.":point } и так далее.. В общем случае, нужна возможность получить список параметров, причем не только самих параметров, но и их атрибутов, таких как название, значение по умолчанию, ограничения, все зависит от задачи. Это сообщение отредактировал(а) Lazin - 20.3.2009, 12:40 |
|||
|
||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
"печатаешь в консоли Radius и ждёшь ввода"
значит надо вводить классы Radius, Height, Width, Lenght
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
В этом случае операции жестко привязаны к субъектам и не могут быть легко расширены. а для тс, насколько я понял, требуется отделить субъекты от операций производимых над ними Это сообщение отредактировал(а) mes - 20.3.2009, 13:05 |
|||
|
||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
mes, не, в этом случае например в объекте Cone будут не 2 поля с разными именами, а массив или вектор из 2х элементов типа Dimention, для ввода которых надо будет обойти этот массив итератором вызывая Input()
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вы не про то.. я про Ваш субъект Radius. В вашей компоновке операция Input жестко привязана к нему. Разницы нет кто из чего состоит. Суть в том что к иерархии субъектов в таком случае нельзя добавить новую операцию, в отличии от подхода с визитором. (см. пример с кодом) Это сообщение отредактировал(а) mes - 20.3.2009, 13:31 |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
накидал пример на скорую руку
суть в том, чтобы вместо иерархии объектов, использовать композицию, в данном случае я использовал boost::fusion для хранения структуры объекта. Примитивные типы для данного примера это point, line и metadata. Объект класса metadata хранит информацию о классе объекта. В принципе, можно добавить метаданные для каждого параметра, каждого объекта, для этого нужно вместо boost::fusion::vector использовать что-то вроде boost::fusison::map, но мне лень это делать) Добавлено через 3 минуты и 2 секунды в принципе, объект класса metadata в каждом новом объекте GenericBody это лишний оверхэд, достаточно создать один объект metadata на каждый "класс"(вариант инстанциирования GenericBody) и в GenericBody хранить только ссылку на такой глобальный объект Добавлено через 6 минут и 40 секунд примерно так:
|
||||
|
|||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
Lazin, выглядит страшно, а работает наверное еще страшнее,
с посетителем куда как лучше, и накладных расходов на память 0 к тому же то что у вас - несколько не соответствует задаче ТС, нужно хранить размеры а не координаты |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
а это и есть паттерн visitor мой пример можно обобщит хоть на хранение килограммов и амперов, смысл в том, что у нас есть набор параметров разных типов(в данном случае это координаты точек и длины), и из них мы строим еще больше классов(линии и окружности), каждый такой класс(GenericBody) имеет ссылку на описатель класса и набор параметров, набор параметров хранится в boost::fusion::vector, что эквивалентно использованию обычной структуры, так-что утверждение неверно Добавлено через 5 минут и 19 секунд по памяти это +4 байта на каждый объект GenericBody и еще +4 байта на указатель на таблицу вирт. функций, по сравнению с обычными структурами по скорости, это один вызов виртуальной ф-ии(в случае если visitor получает указатель на весь класс сразу), против N вызовов(N - количество параметров класса), разница будет незаметна... |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Lazin, Ваш пример хорош, когда Body является просто контейнером параметров. Однако фигура это не просто набор параметров..
к примеру, попробуйте в Вашем примере, применить операцию Draw () Это сообщение отредактировал(а) mes - 20.3.2009, 15:30 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
мой пример хорош, когда код должен хорошо масштабировться в сторону добавления новых классов, так-как все "методы"(объекты клaсса BodyAccessor) не нужно реализовывать для каждого класса. В принципе можно получить любую функциональность, но, если таких классов мало, то проще использовать стандартный подход.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
согласен, но сказал бы так: его хорошо использовать наряду со стандартным подходом, в случае если предполагается также добавление новых классов (например посредством плагина). т.е условная иерархия такая : Line, Cirlce, Quad, Generic. Это сообщение отредактировал(а) mes - 20.3.2009, 15:39 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я бы не сказал, тогда придется вручную реализовывать метод accept для всех вариантов: Line, Circle, Quad etc, в общем тогда проще использовать стандартный подход, и быдлокодить всю иерархию игнорируя тот факт, что объекты Line, Circle, Quad etc, состоят из небольшого набора элементов. Конечно мой пример далек от совершенства, его еще можно сильно улучшить. Но с точки зрения архитектуры, он лучше чем иерархия классов. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
покажите пример удобной реализации функции Draw() для Вашего примера, и если ее недостатки не перекроют достоинства Вашей модели, тогда я с Вами соглашусь. Это сообщение отредактировал(а) mes - 20.3.2009, 16:22 |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
самый простой вариант, можно добавить вирт. ф-ю в класс Body, и специализировать ее для каждого шаблона, но, нужно писать ф-ю для каждой специализации, что плохо
Добавлено через 41 секунду но, можно это сделать и по другому) |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
прежде чем прокомментировать Ваш пример, хотелось бы также понять какой другой вариант Вы имеете ввиду. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я думал не специализировать для каждого GenericBody ф-ю draw, а просто реализовать ее в виде отдельного объекта и передавать ее в GenericBody в качестве параметра шаблона, сейчас покажу...
Добавлено через 10 минут и 35 секунд примерно так...
теперь не обязательно реализовывать метод GenericBody::draw, функторы, занимающиеся отрисовкой фигур можно использовать повторно, либо написать обобщенную версию такого функтора |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в принципе, так можно добавить любую операцию, зависящую от всех данных сразу, например преобразование координат, в то-же время, можно писать обобщенные версии ф-ий, которые работают не со всем объектом целиком, а с его частями, например сериализация, интроспекция. Что-бы написать, к примеру, ф-ю считающую количество вершин геом. фигуры, нужно написать всего один функтор.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ради одних преимуществ, Вы абсолютно потеряли другие, а ведь ничто не мешало пользоваться и тем и другим. Начнем с того что Ваш_метод : 1. открывает приватные переменные и разрешает кому угодно что угодно с ними делать. 2. ведет к потери индивидуальности каждого класса 3. и при всем этом не предоставляет разделение операций от субъектов. да использование внешних функций/функторов как прообраз операции это хорошо. Однако Ваш_метод затрудняет написание и поощряет опечатки.. |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Что под этим имеется ввиду? Да, все классы будут сгенерированы компилятором, то как они бдут работать можно настроить. А можно просто отнаследовать свой класс от Body, и сделать их него настоящую индивидуальность Совсем не сложно сделать метод draw - функцией, или реализовать тот-же самый паттерн visitor, но только для всего объекта, а не для его частей.
привиди пример, как бы ты это сделал, может я чего-то не понимаю...? |
||||
|
|||||
| mes |
|
||||||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
нее... Я не о том, что все через public написано.. это понятно что демонстрационное, а о том что все функции оперируют внутренним состоянием фигуры
вобщем возмущения из за typedef : из за пользования приватными знаниями :
опять из за typedef, что приведет к затруднению перегрузки: ну и конечно BodyAccessor в качестве запроса характеристик от пользователя, как из за доступа к приватным данным, так и из заограничений возможностей запроса. например Circle всегда будет запрашиваться как точка и и длина, а не как центр и радиус, не говоря о том, что не возможно задать двумя точками.
оставить возможности Body только для сериализации и ей подобной. получать типы фигур не typedef, a наследованием. тайпдефить fusion::vector внутри класса фигуры, которой он принадлежит и разгружать ее данные через функции. т.е так
ну а Inputer может быть привязан не к самим фигурам , а к их составляющем; но без допуска к внутренностям объекта. например так:
Это сообщение отредактировал(а) mes - 20.3.2009, 21:37 |
||||||||||||
|
|||||||||||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я немного поковырял этот код, улучшил его, но не так как говорил mes
в общем, я вынес всю шаблонную магию в отдельный класс, от которого можно наследовать ф-ии DrawCircle, и DrawLine, теперь не получают ссылку на sequence, вместо этого они принимают обычный набор параметров, пользователь теперь может писать такие функции:
получать переменные класса можно так-же как и у boost::fusion::vector, с помощью at_c класс GenericBody теперь выглядит намного проще
весь код я решил не выкладывать, вместо этого, код можно получить из моего репозитория на bitbucket - composite_object Добавлено через 3 минуты и 17 секунд ps еще можно сделать так, что-бы конструктор composite_object-a принимал не ForwardSequence, а обычный набор параметров, а потом запаковывал его в последовательность в идеале, пользователь класса не дожен вообще уметь пользоваться boost::fusion |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ага , к самим структурам претензий нет, однако порядок парамeтров все равно жестко прописан на sequence. т.е если вдруг функции нужен только один параметр, она все равно должна иметь в определении всю очередность. в шаблонной магии тоже ничего не режет глаз, однако main.cc все так же и остался полон зависимостей и ограничений. (не буду повторяться какие, потому что основные замечания описаны в предыдущем посте) Это сообщение отредактировал(а) mes - 22.3.2009, 00:55 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
эти ограничения не на пустом месте появились, за все нужно платить в принципе, можно порождать новые классы с помощью наследования, а не typedef
но писанины больше... я не вижу каких-либо проблемм с typedef можно поступить так, как в предидущем примере, но степень обобщенности в этом случае ниже... придется многие ф-ии писать ручками, т.е один класс, одна ф-я, и нельзя их комбинировать... в случае, если потомков Shape/Body очень много, это может быть не так удобно.. с другой стороны передача нескольких лишних параметров по ссылке, вряд-ли вызовает проблеммы с производительностью, так-что, я думаю что все ок... Добавлено через 33 секунды зы обновил код в репозитории, хотя изменений там мало |
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
о производительности тут речи не шло Наш спор в основном вызван тем, что Ваш_метод мы рассматриваем применительно к иерархии фигур. Дело в том что у примитивов фигур очень мало действительно общего, и обобщение на уровне их состояния (приватных данных) только вызывает путаницу.
да каркас класса придется писать ручками, но лично я считаю это, применительно к выше-обсуждаемой задаче, преимуществом. Очень неудобно работать с одним и тем же интерфейсом с Линией, Углом, Трапецией и Кубом. Но это не мешает нам комбинировать их функции. Для этого достаточно разбить на двa условных уровня : функции/функторы и классы их использующее (как в принципе у Вас и обстоит дела с рисованием) проблема не с typedef, а с абсолютной унификацией (потерей индивидуальности) интерфейса (опять же оговорюсж, что лишь применительно к нашей задаче) ну а как иначе.. просто из двух зол выбирают меньшее и еще раз замечу, что основное замечание, было к InputAccessor`у, ради которого в принципе и была применена технология комбинирования. Добавлено через 5 минут и 8 секунд
Как понял с помощью BodyAccessora ? ну и что вернет Ваш функтор применительно к окружности ?! ;) |
||||||
|
|||||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
это просто не удачный пример, вот и все
ну, смотря для чего его использовать, если для сериализации, и подобных сериализации задач, то проблемм нет, для более интелектуальных задач это использовать уже сложнее можно организовать что-то вроде двойной диспетчеризации, передавать в BodyAccessor, не только параметры, но и ссылку на сам объект, в этом случае можно будет перегрузить операции для разных объектов |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
зачем усложнять, когда стандартным подходом это решается нагляднее и проще. ну а в общем мне кажется, что мы уже в принципе пришли к "общему знаменателю" по этой ветке темы Это сообщение отредактировал(а) mes - 22.3.2009, 16:51 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |