|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
CLASHA - Объектно-ориентированное программирование на Си
Author |
Message |
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
Возвращаясь обратно - вот очередная итерация (теперь оно называется CLASHA v0.1 : )
| | | | Code: /* clasha.h - classes for pure C by Shaos
Copyright (c) 2007,2014 A.A.Shabarshin <me@shaos.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef IMPLEMENTATION #ifdef CLASS #undef CLASS #endif #endif
#ifndef CLASS
#ifndef CLASHA_H #define CLASHA_H #include <stdarg.h> #define CLASHA_VER_STR "v0.1" #define CLASHA_VER 0x0001 /* (major<<8)|minor */ #define Q(x) #x #define QQ(x) Q(x) #define $(x,y) $$(x,_,y) #define $$(x,y,z) x##y##z #define NEW(x) $(new,x) #define DEL(x) $(del,x) #define BAD(x) $(bad,x) #define SET(x) $(set,x) #define CON(x) $(x,con) #define CONS(x) $(x,cons) #define DES(x) $(x,des) #define HASH(x) $(x,hash) #ifdef LIGHT #define CLASS_BEGIN(x) typedef struct $(t,x) { #else #define CLASS_BEGIN(x) typedef struct $(t,x) { int _h_,_n_; #ifdef HEAVY #ifdef __cplusplus extern "C" { #endif /* optional class registration for delete method */ void register_class(int h,void(*f)(void*)); /* optional common delete that will call proper method */ void common_delete(void *p); #ifdef __cplusplus } #endif #define delete(x) common_delete(x) #endif #endif #define CLASS_END(x) } x; #ifdef __cplusplus #define PUBLIC extern "C" #else #define PUBLIC extern #endif #define METHOD(x) $(CLASS,x) #define STATIC(x) $(CLASS,x) #define VIRTUAL(x) (*x) #define BEGIN CLASS_BEGIN(CLASS) #define END CLASS_END(CLASS) \ PUBLIC void CON(CLASS) (CLASS*,int,...); \ PUBLIC void CONS(CLASS) (CLASS*,int,va_list); \ PUBLIC void DES(CLASS) (CLASS*); \ PUBLIC CLASS* NEW(CLASS) (int,...); \ PUBLIC void DEL(CLASS) (void*); \ PUBLIC int BAD(CLASS) (CLASS*); #endif
#else
#include <stdlib.h>
/* private methods */
#ifndef LIGHT int HASH(CLASS) = 0;
void SET(CLASS) (CLASS* p) { int c,h=0; char *o,s[] = QQ(CLASS); if(!HASH(CLASS)) { o = s; while((c=*o++)) h += (h<<5) + c; HASH(CLASS) = h; } p->_h_ = HASH(CLASS); } #endif
/* public methods */
int BAD(CLASS) (CLASS* p) { #ifndef LIGHT if(HASH(CLASS)!=p->_h_) return -1; #endif return 0; }
void CON(CLASS) (CLASS *p, int t, ...) { va_list a; #ifndef LIGHT SET(CLASS) (p); #endif va_start(a,t); CONS(CLASS) (p,t,a); va_end(a); }
CLASS* NEW(CLASS) (int t, ...) { int i; CLASS* p; p = (CLASS*)malloc(sizeof(CLASS)*((t>0)?(size_t)t:1)); if(p) { if(t > 0) /* array */ { for(i=0;i<t;i++) { CON(CLASS) (&p[i],0); #ifndef LIGHT p[i]._n_ = t - i; #endif } } else { va_list a; va_start(a,t); #ifndef LIGHT SET(CLASS) (p); #endif CONS(CLASS) (p,t,a); va_end(a); #ifndef LIGHT p->_n_ = 1; #endif } #ifndef LIGHT #ifdef HEAVY register_class(p->_h_,DEL(CLASS)); #endif #endif } return p; }
void DEL(CLASS) (void* v) { CLASS* p = (CLASS*)v; #ifndef LIGHT int i,n = p->_n_; if(BAD(CLASS)(p)) { exit(-1); } #endif DES(CLASS) (p); #ifndef LIGHT p->_h_ = 0; for(i=1;i<n;i++) { DES(CLASS) (&p[i]); p[i]._h_ = 0; } #endif free(p); }
#undef CLASS
#endif
| | | | |
|
12 Oct 2014 20:00 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
Итак, имеется 3 режима:
- LIGHT (требуется опция сборки -DLIGHT) - при этом создаются простые структуры (как в примере в начале топика) без оверхеда;
- NORMAL (режим по умолчанию) - при этом в начале каждого объекта есть 2 инта - хеш класса и кол-во объектов по этому указателю (оверхед 8 байт на объект);
- HEAVY (требуется опция сборки -DHEAVY и файл clasha.c) - как NORMAL, но с возможностью удалять динамически созданные объекты с помощью одной функции delete (корректно удаляются как единичные объекты, так и массивы объектов с вызовом нужного количества деструкторов).
|
12 Oct 2014 20:14 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
Пример класса - class_mya.h: его имплементация - class_mya.c: | | | | Code: #include <stdio.h> #include <string.h>
#include "class_mya.h" /* my class */
#define IMPLEMENTATION
#include "clasha.h" /* bodies */
int $(MyClassA,area) (void* vthis) { MyClassA* this = vthis; return this->id2*(int)strlen(this->str); }
void $(MyClassA,cons) (MyClassA* this, int t, va_list a) { if(t<=MY_CLASSA_DEFAULT) { *this->str = 0; this->id2 = 0; this->area = $(MyClassA,area); } if(t<=MY_CLASSA_CHARP) { strncpy(this->str,va_arg(a,char*),10); this->str[9] = 0; } if(t<=MY_CLASSA_CHARP_INT) { this->id2 = va_arg(a,int); } }
void $(MyClassA,des) (MyClassA* this) { (void)this; }
void $(MyClassA,print) (MyClassA* this) { printf("id=%i str='%s'\n",this->id2,this->str); }
int $(MyClassA,value) = 0;
| | | | |
использование в большой программе: | | | | Code: MyClassA obj2,*pobj2,*pobj3;
$(MyClassA,con) (&obj2,MY_CLASSA_CHARP,"test3"); $(MyClassA,print) (&obj2); $(MyClassA,des) (&obj2);
pobj2 = new_MyClassA(MY_CLASSA_CHARP_INT,"test4",-2); $(MyClassA,print) (pobj2); #ifdef HEAVY delete(pobj2); #else del_MyClassA(pobj2); #endif
pobj3 = new_MyClassA(3); $(MyClassA,print) (&pobj3[0]); $(MyClassA,print) (&pobj3[1]); $(MyClassA,print) (&pobj3[2]); #ifdef HEAVY delete(pobj3); #else del_MyClassA(pobj3); #endif
| | | | |
Обратите внимание на последний пример (как и в C++ если создаём динамический массив, то используется только конструктор по умолчанию) - в режиме LIGHT будет вызван только один деструктор для самого первого объекта (с индексом 0), т.к. функция del_MyClassA не будет знать сколько объектов выделено на указателе, т.е. в режиме LIGHT нельзя создавать динамические массивы объектов, у которых непустые деструкторы... P.S. Запись вида $(class,method) превращается препроцессором в class_method, т.е. можно писать и так, и эдак, однако с $ веселее Знак доллара не поддерживается в стандарте ANSI-C, но поддерживается в GCC и в некоторых старых компиляторах C... P.P.S. Полный набор файлов на поиграца брать тут: http://nedopc.org/nedopc/files/clasha1.zip (5K)
Last edited by Shaos on 12 Oct 2014 22:02, edited 3 times in total.
|
12 Oct 2014 20:20 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
Теперь на CLASHA (который по сути можно считать новым языком программирования с синтаксисом си ; ) надо создать все основные фенечки C++ как то vector, list, slist, queue, deque, map, set и т.д. плюс можно сделать свою ООП надстройку над pthreads для параллельного программирования, а также библиотеку виджетов для построения пользовательских интерфейсов в растре...
|
12 Oct 2014 20:46 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
"Объектно-ориентированное программирование это дорогая катастрофа, которая должна закончится":
http://www.smashcompany.com/technology/ ... h-must-end
P.S. Автор агитирует за функциональный подход...
|
15 Oct 2014 14:41 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Мне вот было очень интересно, когда я с этим разбирался, - а как выглядит объект в машинном коде? Потому что во многих книгах начинают пудрить мозг некоторыми не совсем приятными аналогиями типа: " Представьте себе яблоко, у него есть свойства: форма, цвет ... и т.д." Мне это представляется совсем никуда не годной абстракцией с точки зрения программиста. Потому как, к примеру, окно Винды - это тоже в некотором роде объект, но я неплохо представляю, как это выглядит на ассемблере... А вот ты мог бы привести простой пример, как некий объект реализуется в машинном коде? Кого не спрашивал - все скатываются к " яблокам"...
_________________ iLavr
Last edited by Lavr on 15 Jan 2016 12:56, edited 2 times in total.
|
15 Oct 2014 15:01 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1388 Location: Abakan
|
Если в общем виде - упорядоченная структура ссылок и связанных с ними переменных. При создании объекта, выделяется память на структуру, заполняются ссылки на функции, инициализируются некоторые связанные переменные, в таблицу объектов данного класса добавляется ссылка на эту структуру, потом вызывается функция конструктора, если определена, и конструктор умолчаний, инициализирующий ещё некий объём переменных.
Есть некоторые исключения и отклонения, связанные с конкретной реализацией компилятора.
Вообще, ООП недолюбливают из-за некоторых программистов, пишущих абстракции там где не нужно.
|
15 Oct 2014 22:24 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Вот это я и называю:
Я и сам могу написать похожую общую фразу, ради неё я бы не спрашивал...
_________________ iLavr
|
16 Oct 2014 02:07 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1388 Location: Abakan
|
А чего там интересного в машинном коде по твоему должно быть? Просто набор цифр размерностей byte,word,dword и т.п. Причём это всё появляется динамически при создании объектов, и с ходу дебагером не так просто отловить куда в памяти это попало.
|
16 Oct 2014 05:55 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А интересного там вот что, на мой взгляд: как ни крути, в кодах процессор работает всё же линейно.
А вот объекты - это просто еще один уровень абстракции над машинным кодом, что, впрочем,
присуще любому ЯВУ.
Но ты ещё забыл, что ещё есть и методы.
Так вот мне просто интересно увидеть это конкретно - я так обычно лучше понимаю, как это всё взаимодействует,
нежели, когда всё объясняют абстрактными понятиями типа "каналы... потоки..." и т.д.
Я и сам понимаю, что дебагером это ловить и непросто да и глупо...
Просто люди сочинившие ООП или хорошо знающие ООП должны, видимо, представлять, как это выглядит в коде?
Мне бы достаточно было бы простого примера, но чтобы конкретно увидеть, как объект формируется и как все
его "прибамбасы" выглядят на низком уровне.
Именно мне и интересно - как это всё конкретно "появляется динамически при создании объектов" (и как исчезает - тоже)...
Заодно, кстати: а как ты представляешь себе, выглядит в коде очередь сообщений Винды?
_________________ iLavr
|
16 Oct 2014 09:09 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
Метод это просто подпрограмма, у который первым аргументом (скрытым на уровне ЯВУ) передаётся указатель на объект, с которым она должна работать (обычно называемый this) - вот и всё
P.S. Кстати если я ничего не путаю TASM позволял писать в ООП стиле на ассемблере...
|
16 Oct 2014 09:47 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Ну так показал бы это разочек на низком уровне, тогда бы и было "вот и всё"...
Я бы с любопытством поглядел бы и как выглядит число "this".
_________________ iLavr
|
16 Oct 2014 10:00 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22826 Location: Silicon Valley
|
как выглядит? примерно как 32-битное целое
это ежели речь идёт о 32-битных системах...
|
16 Oct 2014 18:25 |
|
|
jdigreze
God
Joined: 02 Jan 2006 02:28 Posts: 1388 Location: Abakan
|
На zx.pk.ru есть специалист по языкам, зовут Виталием, aka Vitamin. Вполне возможно, он сможет тебе предоставить образцы кода, что во что превращается и как выглядит при исполнении. На сколько я помню, он дипломку защищал по компиляции в ООП. Честно не интересовался. Как программист, думаю, что связанный список, с разбросанными по всей памяти значениями.
|
16 Oct 2014 21:49 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А книги нет подходящей? Когда мне было интересно как выглядят внутренности Винды в коде,
я купил неплохую книжку по программированию под Виндой на ассемблере.
Там, конечно, не про устройство Винды было в основном, но из имеющихся примеров многое
стало понятно.
А вот по ООП подходящей литературы такого плана не попадалось...
PS. Посмотрел поиском... ну, не одного меня похожие вопросы интересуют...
Методы реализации ООП на низком уровне
_________________ iLavr
|
17 Oct 2014 05:00 |
|
|
Who is online |
Users browsing this forum: No registered users and 12 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|