На форумі обговорюються лише питання, пов'язані з олімпіадою
Ви не зайшли.
>>Во первых, ООП - создание в программе собственных объектов. Ничего общего с динамической памятью и задержками процессорного времени оно само по себе не имеет.
Хаха, а как же создание/освобождение классов? Связанная с этим фрагментация памяти и т.д. Я не говорю про те случаи, когда создал класс в начале и уничтожил в конце программы. Я гооврю про большую систему, когда это все постоянно создаёться - удаляеться. Как, например, в 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Джулгаков Дмитрий
Я то же самое написал ![]()
Поза форумом