nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 04 Jun 2024 15:56



Reply to topic  [ 90 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
CLASHA - Объектно-ориентированное программирование на Си 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Возвращаясь обратно - вот очередная итерация (теперь оно называется 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

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


12 Oct 2014 20:00
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Итак, имеется 3 режима:
- LIGHT (требуется опция сборки -DLIGHT) - при этом создаются простые структуры (как в примере в начале топика) без оверхеда;
- NORMAL (режим по умолчанию) - при этом в начале каждого объекта есть 2 инта - хеш класса и кол-во объектов по этому указателю (оверхед 8 байт на объект);
- HEAVY (требуется опция сборки -DHEAVY и файл clasha.c) - как NORMAL, но с возможностью удалять динамически созданные объекты с помощью одной функции delete (корректно удаляются как единичные объекты, так и массивы объектов с вызовом нужного количества деструкторов).

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


12 Oct 2014 20:14
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Пример класса - class_mya.h:
Code:
#ifndef CLASS_MYA_H
#define CLASS_MYA_H

#include "clasha.h"

#define CLASS MyClassA

BEGIN
 int id2;
 char str[10];
 int VIRTUAL(area) (void*);
END

#define MY_CLASSA_DEFAULT    0
#define MY_CLASSA_CHARP     -1
#define MY_CLASSA_CHARP_INT -2

PUBLIC void METHOD(print) (CLASS *this);

PUBLIC int STATIC(value);

#endif

его имплементация - 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)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


Last edited by Shaos on 12 Oct 2014 22:02, edited 3 times in total.



12 Oct 2014 20:20
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Теперь на CLASHA (который по сути можно считать новым языком программирования с синтаксисом си ; ) надо создать все основные фенечки C++ как то vector, list, slist, queue, deque, map, set и т.д. плюс можно сделать свою ООП надстройку над pthreads для параллельного программирования, а также библиотеку виджетов для построения пользовательских интерфейсов в растре...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


12 Oct 2014 20:46
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
"Объектно-ориентированное программирование это дорогая катастрофа, которая должна закончится":

http://www.smashcompany.com/technology/ ... h-must-end

P.S. Автор агитирует за функциональный подход...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


15 Oct 2014 14:41
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Shaos wrote:
"Объектно-ориентированное программирование это дорогая катастрофа, которая должна закончится"...

Мне вот было очень интересно, когда я с этим разбирался, - а как выглядит объект в машинном коде?

Потому что во многих книгах начинают пудрить мозг некоторыми не совсем приятными аналогиями типа:
"Представьте себе яблоко, у него есть свойства: форма, цвет ... и т.д."

Мне это представляется совсем никуда не годной абстракцией с точки зрения программиста.

Потому как, к примеру, окно Винды - это тоже в некотором роде объект, но я неплохо представляю,
как это выглядит на ассемблере...

А вот ты мог бы привести простой пример, как некий объект реализуется в машинном коде?
Кого не спрашивал - все скатываются к "яблокам"... :-?

_________________
iLavr


Last edited by Lavr on 15 Jan 2016 12:56, edited 2 times in total.



15 Oct 2014 15:01
Profile
God

Joined: 02 Jan 2006 02:28
Posts: 1388
Location: Abakan
Reply with quote
Post 
Если в общем виде - упорядоченная структура ссылок и связанных с ними переменных. При создании объекта, выделяется память на структуру, заполняются ссылки на функции, инициализируются некоторые связанные переменные, в таблицу объектов данного класса добавляется ссылка на эту структуру, потом вызывается функция конструктора, если определена, и конструктор умолчаний, инициализирующий ещё некий объём переменных.

Есть некоторые исключения и отклонения, связанные с конкретной реализацией компилятора.

Вообще, ООП недолюбливают из-за некоторых программистов, пишущих абстракции там где не нужно.


15 Oct 2014 22:24
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Lavr wrote:
...привести простой пример, как некий объект реализуется в машинном коде?

jdigreze wrote:
Если в общем виде - упорядоченная структура ссылок и связанных с ними переменных. При создании объекта, выделяется память на структуру, заполняются ссылки на функции, инициализируются некоторые связанные переменные, в таблицу объектов данного класса добавляется ссылка на эту структуру, потом вызывается функция конструктора, если определена, и конструктор умолчаний, инициализирующий ещё некий объём переменных.

Вот это я и называю:
Lavr wrote:
Кого не спрашивал - все скатываются к "яблокам"... :-?

Я и сам могу написать похожую общую фразу, ради неё я бы не спрашивал...

_________________
iLavr


16 Oct 2014 02:07
Profile
God

Joined: 02 Jan 2006 02:28
Posts: 1388
Location: Abakan
Reply with quote
Post 
А чего там интересного в машинном коде по твоему должно быть? Просто набор цифр размерностей byte,word,dword и т.п. Причём это всё появляется динамически при создании объектов, и с ходу дебагером не так просто отловить куда в памяти это попало.


16 Oct 2014 05:55
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
jdigreze wrote:
А чего там интересного в машинном коде по твоему должно быть?

А интересного там вот что, на мой взгляд: как ни крути, в кодах процессор работает всё же линейно.
А вот объекты - это просто еще один уровень абстракции над машинным кодом, что, впрочем,
присуще любому ЯВУ.

Но ты ещё забыл, что ещё есть и методы.

Так вот мне просто интересно увидеть это конкретно - я так обычно лучше понимаю, как это всё взаимодействует,
нежели, когда всё объясняют абстрактными понятиями типа "каналы... потоки..." и т.д.

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

Мне бы достаточно было бы простого примера, но чтобы конкретно увидеть, как объект формируется и как все
его "прибамбасы" выглядят на низком уровне.

Именно мне и интересно - как это всё конкретно "появляется динамически при создании объектов" (и как исчезает - тоже)... 8)

Заодно, кстати: а как ты представляешь себе, выглядит в коде очередь сообщений Винды?

_________________
iLavr


16 Oct 2014 09:09
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Метод это просто подпрограмма, у который первым аргументом (скрытым на уровне ЯВУ) передаётся указатель на объект, с которым она должна работать (обычно называемый this) - вот и всё :)

P.S. Кстати если я ничего не путаю TASM позволял писать в ООП стиле на ассемблере...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


16 Oct 2014 09:47
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Shaos wrote:
Метод это просто подпрограмма, у который первым аргументом (скрытым на уровне ЯВУ) передаётся указатель на объект, с которым она должна работать (обычно называемый this) - вот и всё...

Ну так показал бы это разочек на низком уровне, тогда бы и было "вот и всё"... :wink:
Я бы с любопытством поглядел бы и как выглядит число "this".

_________________
iLavr


16 Oct 2014 10:00
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22826
Location: Silicon Valley
Reply with quote
Post 
Lavr wrote:
Shaos wrote:
Метод это просто подпрограмма, у который первым аргументом (скрытым на уровне ЯВУ) передаётся указатель на объект, с которым она должна работать (обычно называемый this) - вот и всё...

Ну так показал бы это разочек на низком уровне, тогда бы и было "вот и всё"... :wink:
Я бы с любопытством поглядел бы и как выглядит число "this".


как выглядит? примерно как 32-битное целое :)

это ежели речь идёт о 32-битных системах...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


16 Oct 2014 18:25
Profile WWW
God

Joined: 02 Jan 2006 02:28
Posts: 1388
Location: Abakan
Reply with quote
Post 
Lavr wrote:
Я и сам понимаю, что дебагером это ловить и непросто да и глупо...
Просто люди сочинившие ООП или хорошо знающие ООП должны, видимо, представлять, как это выглядит в коде?
На zx.pk.ru есть специалист по языкам, зовут Виталием, aka Vitamin. Вполне возможно, он сможет тебе предоставить образцы кода, что во что превращается и как выглядит при исполнении. На сколько я помню, он дипломку защищал по компиляции в ООП.

Lavr wrote:
Заодно, кстати: а как ты представляешь себе, выглядит в коде очередь сообщений Винды?
Честно не интересовался. Как программист, думаю, что связанный список, с разбросанными по всей памяти значениями.


16 Oct 2014 21:49
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
jdigreze wrote:
На zx.pk.ru есть специалист по языкам, зовут Виталием, aka Vitamin. Вполне возможно, он сможет тебе предоставить образцы кода, что во что превращается и как выглядит при исполнении.

А книги нет подходящей? Когда мне было интересно как выглядят внутренности Винды в коде,
я купил неплохую книжку по программированию под Виндой на ассемблере.

Там, конечно, не про устройство Винды было в основном, но из имеющихся примеров многое
стало понятно.

А вот по ООП подходящей литературы такого плана не попадалось...


PS. Посмотрел поиском... ну, не одного меня похожие вопросы интересуют... :wink:
Методы реализации ООП на низком уровне

_________________
iLavr


17 Oct 2014 05:00
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 90 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.