LINUX.ORG.RU

В чём суть ООП?


3

5

С точки зрения манеры проектирования, а не особенностей реализации С++ там CLOS. Вот например я использую определения классов и даже иногда наследование как узнать пишу ли я в ООП стиле?

★★★★★

Последнее исправление: ados (всего исправлений: 1)

Ответ на: комментарий от drBatty

А полиморфизма нет вообще.

ну в Win32 API есть например полиморфизм. Только используется без нормального рантайма, больше как «не совсем» ООП API.

когда

struct FILE {
int tag;    // objid
int class; //typeof(class FILE)
char data[0]; //see below
void  *methods[0];

char * path; 
int fd;

bool (*m_open)(); //виртуальный метод, для разнообразия
.....
};


 FILE_t* FILE_ctor(char *_path, int _fd) {

  FILE_t *f = (FILE_t*)calloc(1,sizeof(FILE_t));

 if (!f) {
  FILE_setProperty("path",_path, CLASS_OFFSET(FILE,path)); // path = _path;
  FILE_setProperty("fd",_fd,CLASS_OFFSET(FILE,fd));              //fd=_fd;

  setOID(FILE,f->tag );
  setClass(FILE,f->class);
 setData(FILE,f->data);
 setVTable(FILE,f->methods);
  }
  return f;
}
...
bool FILE_open(FILE_t * this) {
 if (this) {
   if (this->methods) {
    if (!m_open) {
     m_open= callVMethod(this,this->methods,"FILE","open", BASE_CLASS_OF(FILE)); //диспетчеризация в унаследованный полиморфный метод через methods[0]
     }
     (*m_open)(); //вызов FILE_open_imp
   }
... 
}   
...
}

...
bool FILE_open_imp(FILE_t * this) {
  fd = open(path,...);
...
}
...

// вызов метода open

FILE_t * file=FILE_ctor("/dev/null",0);
FILE_open(file); //диспетчеризуется в FILE_open_imp или BASECLASS_FILE_open_imp
...
FILE_dtor(file); // + FILE_close(file);

 
 
 

cм. здесь

То есть:

велосипед для реализации полиморфизма.

структура с переменной длиной. Методы/свойства структуры-класса можно вызывать: свойства через data[0], методы через methods[0] — если мы заранее, на уровне рантайма знаем sizeof структуры, типы, к которым надо приводить => можно написать враппер типа FILE_setProperty который препроцессором раскроется в «установить нужное поле экземпляра, с учётом наследования», и аналогично для виртуальных методов: если указатель на метод не проинициализирован, метод ищется в базовом классе, вызывается нужная реализация _imp (из базового или дочернего)

Что-то можно навелосипедить препроцессором, для чего-то без поддержки в рантайме не обойтись.

сложно назвать «инкапсуляцией

не , инкапсуляция не в этом. Допустим у „класса“ FILE есть публичный метод open и приватный setPath, например.

Тогда :

  • один класс — один модуль (файл с исходником)
  • FILE_open делаем extern
  • FILE_setPath делаем static

Итого: „метод“ open экспортируется из модуля, „метод“ setPath — нет („приватный“).

Получили инкапсуляцию, распишитесь.

anonymous
()
Ответ на: комментарий от anonymous

Ну простой вывод:

Не только простой, но и примитивный.

ООП удобно для доработок реорганизацией структуры классов: когда нужно переместить метод/свойство в другой класс, при этом возможно понадобится изменять связанные классы, которые вызывают/вызываются этим классом.

ООП тут не нужно. Грамотная техника модульности позволяет сделать разработку как проще так и приятнее. Другое дело что техника модульности требует более высокого уровня подготовки и професионализма чем порог вхождения до тупого следования в рамках ООП (и именно из-за этого «слабаки и среднячки» используют python/java/c# ...).

Процедурное программирование удобно когда нужно добавить новый метод, не изменяя структуру класса. Которая уже сложилась и изменяться не будет. Добавление нового «метода» (функции с первым параметром this, остальными параметрами метода) не требует изменений в других местах.

То есть: когда объектная модель уже сложилась и достаточно её «расширять» вот так — хватит и процедурного программирования. Когда нужно изменять структуру классов, отношения — нужно ООП в том или ином виде.

Вообще говоря читать ваше сообщение, мягко говоря, неприятно. Очень поверхностный и однобокий анализ вкупе с недалекостью взглядов. Сразу становится интересно, сколько же годиков вы знакомы с терминами программирования (и уровень образования). Ведь мало что вы модульность не вспомнили, так вы и не вспомнили ничего кроме процедурного. Почему так? Откуда же вы такие делаетесь?

anonymous
()
Ответ на: комментарий от anonymous

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

ну я и не говорил, что наследование необходимо в «ООП вообще», оно необходимо в C++, дабы избежать велосипедов с квадратными колёсами.

патаму что C++ — это язык реализации объектной модели VTABLE (с таблицей виртуальных методов).

истинно так.

ага, а мы заранее должны знать что метод будет виртуальным, потому что иначе --взлетит не та утка. посему это не Ъ полиморфизьм.

не возбраняется сделать _все_ public/protected методы виртуальными, даже и те, которые не виртуальные. Оверхед небольшой, всего один лишний указатель на экземпляр класса, который обычно и так есть (уверен, что во всяких питонах оверхед намного больше). Тогда полиморфизм будет вполне Ъ.

drBatty ★★
()
Ответ на: комментарий от anonymous

велосипед для реализации полиморфизма.

угу. поубивал-бы...

Итого: «метод» open экспортируется из модуля, «метод» setPath — нет («приватный»).

да. я знаю. IRL это выглядит немного не так - ЕМНИП таблица у линковщика всего одна, и он её строит на основе хидеров с объявлениями. Что _там_ написано, то и построит. В принципе, в хидерах и нет setPath, но можно таки и вставить. Ну и получить недокументированную функцию, которая работает таки быстрее. Чем, собственно, все и пользуются. Ломая совместимость в обе стороны, и порождая код, который работает в зависимости от погоды на Марсе.

В C++ такого рода быдлокод получить сложнее. Впрочем, я уж и не в курсе, возможно специалисты из мысы таки получили? Иметь недокументированные функции тупо выгодно. Тупо по $$$.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.