На форумі обговорюються лише питання, пов'язані з олімпіадою
Ви не зайшли.
>>Во первых, ООП - создание в программе собственных объектов. Ничего общего с динамической памятью и задержками процессорного времени оно само по себе не имеет.
Хаха, а как же создание/освобождение классов? Связанная с этим фрагментация памяти и т.д. Я не говорю про те случаи, когда создал класс в начале и уничтожил в конце программы. Я гооврю про большую систему, когда это все постоянно создаёться - удаляеться. Как, например, в 3Д играх - когда есть менеджер сцены, который контролирует объекты на сцене и производит с ними различные манипуляции. И про скорость Делфи я имел ввиду следующее - проводился опыт - в цикле создавались/уничтожались сложные иерархические объекты. Тест был проведен и на gcc, и на MS VC++, и на Delphi - результат - gcc медленнее всех, а Delphi - быстрее в 4 раза.
Мощь Делфи в ООП больше чем в С++. Например, использование скриптовых языков в Делфи легче, т.к. Делфи проддерживает метаклассы, а С++ - нет. Только с помощью громоздкой boost. И когда ты говорищь, что ООП сильнее у С++ - поясняй свою точку зрения фактами.
Насчет микрософта, да, ошибся, ссори. В таком случае - что стоит поставить под юникс - Kylix?
Поза форумом
Кароч, Jura не понял, в чем разница между СТЛ и ООП. СТЛ - это стандартная библиотека шаблонов, там есть много полезных вещей, которые помогают программисту (напр, динамические строки, списки и т.д.). Да, они используют динамическую память и в принципе замедляют работу программы. Но!
1. на различных конкурсах, где важна скорость набора программы (ТопКодер, ТТБ, АСМ, etc) - это незаменимый помощник
2. ООП!=СТЛ (ООП<>СТЛ)
3. что значит стабильность на олимпиаде не нужна???! И на олимпиаде тоже программа должна четко и корректно.
Ты на micro$oft не ровняйся, они ось без глюков сделать не могут, а ты про компилятор говоришь! Если тебя интересует нормальный компилятор, возьми Borland C++Builder или GNU GCC. Надежность проверена!
А ФриПаскаль используется на этой олимпиаде именно из-за кроссплатформенности. Из-за того, что паскаль имеет множество расширений, поэтому одноплатформенные компиляторы не подходят - разные оси.
Поза форумом
2Jura:
Кто тебе сказал такую ГЛУПОСТЬ про gcc?? Да и вообще ООП в паскале было просто нагло слизано с C++, при этом не даже не вполне удачно (ограничения паскаля однако)!!!
Если ты хочешь провести сравнение - кидай сюда исходники, посмотрим!
Поза форумом
Я хоть и паскалист, но С++ знаю немного, и моих знаний хватает, чтоб понять разницу между СТЛ и ООП. Я имелл виду использование ООП, а не СТЛ.
Стабильность - не в том смысле, ну да ладно.
Насчет компиляторов, то у micro$oft`а может и глючный компилятор, но быстрый. Билдеру до него далеко, Билдер "даже" медленнее Делфи. Насчет gcc - то это скорее выбор для кроссплатформености, как и ФриПаскаль.
Это всё не то - моя первоначальная мысль была в том, что ООП на олимпиадах - нет, а без ООП программист - не есть программист. И это не правильно, что на олимпиадах, где вспринципе должны быть программисты - готовят просто тех, кто идеально знает некоторые, скажем прямо - спецефические алгоритмы (в жизни они редко встретяться), но не знают ООП, или команды той или иной ОСи.
Но это просто мои рассуждения, моё ИМХО. Поэтому просьба не пинать - а подумать над этим...
Поза форумом
имхо на олимпиадах можно спокойно использовать ООП. и при этом динамическая память не используеться. все можно делать в стеке, как с обычными переменными
Поза форумом
Ээм.. Что значит - нагло слизанно?
1) Это все равно что сказать - арифметика была "нагло слизана" - ведь принципы ООП одни на всех.
2) Насчет скорость gcc - то это был простой синтетический тест.
3) КАКИЕ ограничения у паскаля?? Очень бы хотелось узнать..
Вот пример ограничения С++ в ООП:
Есть:
объект А
объект B (наследник А)
объект С (наследник А)
объект D (наследник А)
A B C D - очень разные объекты, у каждого определен метод assign, который копирует в текущий объект информацию из объекта, который подаеться в этот метод. Т.е. происходит присваивание объектов.
Есть массив А. (в котором могут храниться как объекты типа А, так и наследники - B,C,D)
Надо написать процедуру добавления в этот массив любого из классов (A,B,C,D)
В Делфи делаеться так:
type
MetaClass=class of A; // это у нас метакласс для типа А, и его наследников
var
AAA:array of A;
procedure AddToArray(Obj:A);
var l:integer;
Meta:MetaClass;
begin
l:=length(AAA);
Setlength(AAA,l+1); // это не важно - можно было и через property, но я для наглядности
Meta:=MetaClass(Obj.ClassType); // приведем глобальный метакласс к локальному MetaClass
// тут НУЖНО (по условию) сделать именно копирование, а не указатель передать - мало что мы будем делать с объектом вне этой процедуры.
AAA[l]:=Meta.Create;
AAA[l].assign(Obj);
end;
Вот вам и "ограничения" паскаля..
Поза форумом
Да конечно можно использовать! Только я не видел ни одной нормальной задачи где НУЖНО было бы!
Насчет языков- я считаю, что важен музыкант, а не инструмент, так что хватит холивар разжигать.
Ограничений нет ни в паскале, ни в с++, ни в бейсике - написать что угодно можно на чем угодно. На этом и закончим с ними..
Відредаговано Jura (2006-11-09 11:49:15)
Поза форумом
Про метаклассы. Во первых: что ты получил в результате в массиве AAA? Кучу разнородных объектов. Тот еще подарок. Такая гадость вообще может понадобиться только в одном случае: ты потом пройдешься по ним виртуальными функциями-членами. Кстати, через метаклассы можно вызывать виртуальные функции-члены?
В С++ вместо метаклассов с успехом работают ссылки и указатели. На примере с массивом все же часто удобнее использовать auto_ptr, чтобы не заботиться о удалении элементов. Кстати, если ты заметил, то метаклассы тоже используют динамическую память.
По поводу же ООП. Не знаю, как в делфи, но в С++ объекты не обязаны выделяться в куче. Объекты можно спокойно задавать так же, как и переменные элементарных типов. Про ООП на олимпиадах я уже писал 2 раза. Почитай мои посты в конце концов. Про ограничения в языках и написание чего угодно и на чем угодно я тактично умолчу: что-то не слышал я про выход ОС на бейсике, да и на паскале...
Поза форумом
>Кстати, через метаклассы можно вызывать виртуальные функции-члены?
Конечно.
>В С++ вместо метаклассов с успехом работают ссылки и указатели.
Дык и в Делфи тоже.
>Кстати, если ты заметил, то метаклассы тоже используют динамическую память.
Ну да - но при чем тут динамическая память? Конечно она используется.
>Объекты можно спокойно задавать так же, как и переменные элементарных типов.
Всмысле? А в Делфи что нельзя?
>что-то не слышал я про выход ОС на бейсике, да и на паскале...
То что половина ОСей написана на асме, а другие частично на сях еще ничего не значит. Это не доказывает того что на других языках нельзя их написать
Приведи мне хоть один пример того чего не возможно написать на Делфи, что можно написать на С++. Вот - вот (с)
Поза форумом
Jura
Неделю назад в чате ттб перед контестом пытались написать на делфе аналог такого кода:
#include <iostream> class cl { public: int val; int count_func() {return val*2;} }; int main() { int cl::*var=&cl::val; int (cl::*func)()=&cl::count_func; cl obj; obj.val=5; std::cout<<obj.*var<<" "<<(obj.*func)()<<std::endl; return 0; }
Тогда никто так и не придумал, как взять указатель на член класса в делфе.
Поза форумом
ссори плохо читаю сишный код. Не мог бы ты объяснить что есть
int cl::*var=&cl::val;
int (cl::*func)()=&cl::count_func;
Я так понял это переопределяет каким то образом сам класс cl, вставляя в него указатели var и func. Верно? Ну тогда извини - я счастлив что такой возможности нет в делфи - т.к. это было бы крайним извратом и источником ошибок.
А вообще указатель на член класса берется так же как и не на член класса - в чем проблема? Разве что функциям/процедурам надо дописывать "of object"
program Project1; {$APPTYPE CONSOLE} uses SysUtils; type Cl=class public val:integer; function count_func:integer; end; function Cl.count_func:integer; begin result:=val*2; end; var obj:cl; p1:pinteger; // можно pointer но потом надо делать typecast p2:function:integer of object; begin obj:=cl.create; p1:=@obj.val; p2:=obj.count_func; obj.val:=5; write(p1^,' ',p2); obj.free; end.
Я вообще правильно понял тебя - или ты под "взять указатель на член класса" всё таки имел ввиду что-то другое?
Відредаговано Jura (2006-11-11 09:38:02)
Поза форумом
int cl::*var=&cl::val; int (cl::*func)()=&cl::count_func;
Это создание указателя на функцию-член класса. В самом простом случае указатель на фунцию-член хранит смещение члена относительно указателя this.
переменная var типа
int cl::*
может указывать на любой член типа инт класса cl.
Использоваться этот указатель может только на конкретном екземпляре класса obj. Попробую пояснить другим примером:
#include <iostream> class my_class { public: int x,y; }; int main() { my_class obj; int my_class::*var; obj.x=1; obj.y=2; var=&my_class::x; std::cout<<obj.*var<<std::endl; // выдаст 1 var=&my_class::y; std::cout<<obj.*var<<std::endl; // выдаст 2 return 0; }
Поза форумом
reiten написав:
Код:
int cl::*var=&cl::val; int (cl::*func)()=&cl::count_func;Это создание указателя на функцию-член класса. В самом простом случае указатель на фунцию-член хранит смещение члена относительно указателя this.
переменная var типа
int cl::*
может указывать на любой член типа инт класса cl.
Использоваться этот указатель может только на конкретном екземпляре класса obj. Попробую пояснить другим примером:Код:
#include <iostream> class my_class { public: int x,y; }; int main() { my_class obj; int my_class::*var; obj.x=1; obj.y=2; var=&my_class::x; std::cout<<obj.*var<<std::endl; // выдаст 1 var=&my_class::y; std::cout<<obj.*var<<std::endl; // выдаст 2 return 0; }
действительно, указатель на член конкретного класса в делфях создать нельзя. Но создавать указатели на функцию класса можно спокойно. Единственная разница, что этой переменной-функции можно присвоить метод любого класса с такой сигнатурой:
type TClass1 = class public function func1(i : Integer) : Integer; begin Result := i; end; end; TClass2 = class public function func1(i : Integer) : Integer; begin Result := i*2; end; end; .... type TPtr = function (i : Integer) : Integer of object; var ptr : TPtr; obj1 : TClass1; obj2 : TClass2; begin ... Ptr := obj1.func1; Write(Ptr(20)); Ptr := obj2.func2; Write(Ptr(20)); end;
хотя возможность ограничить ссылку конкретным классом в С++ вряд ли когдато понадобиться...
Поза форумом
Ага, ясно. Любопытно довольно, но не думаю что это составляет особую пользу... Ну по крайней мере обойтись без этого можно легко - т.е. это не чего "невозможно написать на Делфи"...
2Джулгаков Дмитрий
Я то же самое написал
Поза форумом