|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
CLASHA - Объектно-ориентированное программирование на Си
Author |
Message |
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
Самые последние исходники CLASHA с примерами брать тут а обсуждение начинать читать отсюда (12 октября 2014)...Задумался я о том, можно ли на голом Си покрыть всё разнообразие возможностей объектно-ориентированного программирования, которое даёт Си++. Например мой простой стиль C++ программирования легко переводится в C, но что делать с непростыми стилями? Начнём с простого - имеем вот такой код на C++: На голом C это можно записать так: А теперь подумаем как нам таким способом изобразить трёх котов ООП - инкапсуляцию, наследование и полиморфизм...
Last edited by Shaos on 17 Oct 2014 14:09, edited 4 times in total.
|
18 Sep 2007 20:18 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
В вышеприведённом примере полиморфизмом и не пахнет, т.к. мы используем разные функции для замены конструкторов с разным набором аргументов. Вот что получится если заюзать stdarg.h:
Тут мы воспользовались неким дополнительным аргументом t, который говорит функции-конструктору о том, какой набор аргументов следует использовать. Для простоты можно завести набор дефайнов для этого "конструктора": Пример кода, использующий этот "класс": Для более компактного представления такого подхода можно соорудить вот такой вспомогательный инклуд: | | | | Code: // file shaclass.h #ifndef CLASS #define CON(x,y) x##y #define NEW(x) CON(new_,x) #define DEL(x) CON(del_,x) #define CONS(x) CON(x,_cons) #define CONS_(x) CON(x,_cons_) #define DEST(x) CON(x,_dest) #define CLASS_BEGIN(x) typedef struct _##x { #define CLASS_END(x) } x; #define PUBLIC extern #define METHOD(x,y) CON(x,_##y) #define BEGIN(x) CLASS_BEGIN(x) #define END(x) CLASS_END(x) \ PUBLIC void CONS(CLASS) (CLASS *this, int t, ...); \ PUBLIC void CONS_(CLASS) (CLASS* this, int t, va_list a); \ PUBLIC void DEST(CLASS) (CLASS *this); \ PUBLIC CLASS* NEW(CLASS) (int t, ...); \ PUBLIC void DEL(CLASS) (CLASS *this);
#else
void CONS(CLASS) (int t, ...) { va_list a; va_start(a,t); CONS_(CLASS) (p,t,a); va_end(a); } CLASS* NEW(CLASS) (int t, ...) { CLASS* p; va_list a; va_start(a,t); p = (CLASS*)malloc(sizeof(CLASS)); if(p!=NULL) CONS_(CLASS) (p,t,a); va_end(a); return p; } void DEL(CLASS) (CLASS* p) { DEST(CLASS) (p); free(p); }
#endif
| | | | |
И пример кода: | | | | Code: #include "shaclass.h"
#define CLASS MyClass
BEGIN(CLASS) int id; char str[10]; END(CLASS)
PUBLIC void METHOD(CLASS,Print) (CLASS *this);
#include "shaclass.h" // bodies
#define MY_CLASS_VOID 0 #define MY_CLASS_CHARP 1 #define MY_CLASS_CHARP_INT 2
void MyClass_cons_(MyClass* this, int t, va_list a) { if(t>=MY_CLASS_VOID) { *this->str = 0; this->id = 0; } if(t>=MY_CLASS_CHARP) { strncpy(this->str,va_arg(a,char*),10); this->str[9] = 0; } if(t>=MY_CLASS_CHARP_INT) { this->id = va_arg(a,int); } }
void MyClass_dest(MyClass* this) { }
void MyClass_Print(MyClass* this) { printf("id=%i str='%s'\n",this->id,this->str); }
main() {
MyClass obj,*pobj;
MyClass_cons(&obj,MY_CLASS_CHARP,"test"); MyClass_Print(&obj); MyClass_dest(&obj);
pobj2 = new_MyClass(MY_CLASS_CHARP_INT,"test2",2); MyClass_Print(pobj2); del_MyClass(pobj2);
}
| | | | |
|
18 Sep 2007 21:51 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
К наследованию подойдем с другой стороны:
На голом си можно сделать вот что:
|
20 Sep 2007 19:57 |
|
|
CHRV
God
Joined: 29 Dec 2003 01:00 Posts: 1101 Location: Москва
|
Для темплайтов мы написали свою распарсилку котроая умеет разворачивать в код (что по сути и делается компилятором), так как у нас один компилер для 68К не умеет работать с темплайтами.
Большая проблема - это множественное наследование (ну если учесть что это зло, то можно требовать не использовать)...
_________________Московский филиал NedoPC http://www.nedopc.com
|
20 Sep 2007 23:24 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
А что GCC для m68k уже отменили?
Ну на чистом Си множественное наследование вполне себе возможно - единственное ограничение что нельзя использовать теже самые имена для членов классов в наследуемых "классах".
|
21 Sep 2007 14:22 |
|
|
CHRV
God
Joined: 29 Dec 2003 01:00 Posts: 1101 Location: Москва
|
Gcc строит крайне неоптимальный код, во вторых под него нет отладчика, в третьих девайс оптимизирован под SDS.
_________________Московский филиал NedoPC http://www.nedopc.com
|
22 Sep 2007 11:04 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
Неправильный вы GCC смотрели. Для x86 и Sparc строит более чем оптимальный код (опцию -O2 не забыли включить?
А в качестве отладчика GDB для GCC всю жизнь выступал...
Что такое SDS?
|
22 Sep 2007 12:44 |
|
|
DawnON.com
Novelist
Joined: 17 May 2008 15:26 Posts: 30 Location: 79.124.149.121
|
Во времена, когда Модула соперничала с Трубо-Паскалем, а C с C++ и с Паскалем,
а не изысканные вина не хватало денег (тем более у меня, мне даже анкету участника Gree Card Lottery фирма посредник заполнила так дёшево чтобы потом выбросить). Так чтобы восполнить недостаток в напитках исполненных тонкого аромата и самое главное пьянящих, приходилось смешивать отдельно пьянящее и отдельно ароматное. И походило это на смешивание объектно-ориентированного программирования с языком C в некоторых трансляторах (компиляторах) и стандартах формальных грамматик (языках и версиях языков). Но были такие кто потреблял продукт необычно- т.е. не смешивая и назывался такой продукт "чистяк".
Вот Вам объектно-ориентированное программирование на чистом C.
| | | | Code: #define Class1 class1 *
struct class1 { int some, other; };
Class1 class1_new() { Class1 this; this=(void *)malloc(sizeof(struct class1)); this->some=0; this->other=0; return(this); };
void class1_delete(Class1 this) { free (this); };
void class1_some(Class1 this, int val) { this->some=val; }
void class1_other(Class1 this, int val) { this->other=val; };
int class1_together(Class1 this) { return(this-some+this->other); };
/*Class Dawn from DawnON.com*/
#define Dawn dawn * struct dawn { int lighting; };
Dawn DawnON() { Dawn this; this=malloc(sizeof(struct dawn)); this->lightning=0; return(this); };
void DawnOFF(Dawn this) { free(this); }
void DawnLightning(Dawn this) { this->lightning=1; };
int DawnStatus(Dawn this) { return(this->lightning); };
/* class Dawn is perfected */
int main(int so_many, char * such_arguments) { Class1 ex1, ex2;
Dawn on_monday, on_tuerday;
ex1=class1_new(); ex2=class1_new();
class1_some(ex1,5); class1_other(ex1,7);
class1_some(ex2,class_together(ex1)); class1_other(ex2,2);
printf("ex2->together=%d\n",class1_together(ex2));
class1_delete(ex1); class1_delete(ex2);
on_monday=DawnON(); DawnLightning(on_monday); if (DawnStatus(on_monday)) { printf("If is a dawn on monday\n"); } DawnOFF(on_monday);
on_thuerday=DawnON(); if (!DawnStatus(on_thuersday)) { printf ("A dawn not yet came on thuerday"); } DawnLightning(on_thuerday); DawnOFF(on_thuersday); /* Monday 19 of May 2008 11:53 p.m. */ }
| | | | |
Приблизительно к такому виду компилятор внутри преобразовывает программу когда транслирует её с C++ в более удобные для генерации кода абстракции.
Много других свойств C++ на прямую не связаны с Объектно Ориентированным
Программированием и по немножку появляются в новых спецификациях C.
Но по большему счету C уже устарел многие его свойства делают его менее привлекательным даже по сравнению с PL/2 (его конкурентом на этапе утверждения как языка программирования общего назначения).
Last edited by DawnON.com on 20 May 2008 11:44, edited 2 times in total.
|
19 May 2008 13:51 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
Это уже давно не так
Программирование на C++ сегодня - это в первую очередь темплейтное метапрограммирование...
|
19 May 2008 14:58 |
|
|
DawnON.com
Novelist
Joined: 17 May 2008 15:26 Posts: 30 Location: 79.124.149.121
|
Вообще-то я говорил от трансляторе с этого языка, а не о стиле программирования.
(Как работает программа транслятор (компилятор), а не как работает программист).
Под генерацией кода подразумевается некое автоматизирование действие выполняемое посредством некого аппаратного устройства, или программно аппаратного комплекса, результатом которого есть некоторый машинный код или некоторые данные в некотором формате содержащие машинный код.
А не как не процесс создания исходного кода программы программистом (автором такого кода).
Касательно вашего определения как темплейтного метапрограммирования, если это программирование с использованием неких штампов/клише/темплейтов посредством некого объединение по неким мета-принципам то:
- Такое программирование может быть применено и к объектно ориентированному, и не к объектно ориентированному.
- и исходит скорее из свойств языка C++ описанных в некоторых параметрах, напрямую не относящихся к объектно ориентированному.
- Смею предположить что мета программирование - больше предрасположено проявляться в так называемом функциональном программировании, до которого практически весь код на C++ увиденный мною в исходных кодах аж никак не относиться.
Мало того полезная идея объектно ориентированного программирования и изящной лексики в стиле языка C практически сходят не нет в современных мегабайтах кода, который непонятно что делает.
Лично я работаю над новым языком программирования, в котором осталось не так много места для творчества как некоторых неявно представленных запросов индустрии. По крайней мере уже несколько раз концепция такого языка кардинально улучшилась после различного рода дискусий (обсуждений), на тему языков программирования. Но не все сразу.
|
20 May 2008 11:37 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А есть какие-либо более-менее стандартные приёмы, когда алгоритм,
реализованный на С++ желательно откатить на С?
Сталкивался с этим довольно часто, поскольку в качестве С/С++ юзаю
Борланд Билдер. На нём некоторые конструкции - в упор не идут...
Что-то у меня получается порой переделать довольно легко, а что-то
в упор не откатывается.
Совет - выкинь ты свой Билдер - неприемлем. Я на нём всёж довольно
много работал, привык...
|
12 Apr 2011 16:29 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22782 Location: Silicon Valley
|
сильно зависит от того насколько изысканные изыски сиплюсов заюзаны в алгоритме - если эзотерика последних лет, то вряд ли...
|
12 Apr 2011 17:30 |
|
|
d_wanderer
Senior
Joined: 28 Feb 2006 21:34 Posts: 180
|
Саш, тут Linus Torvalds написал об использовании C++ в весьма колоритных выражениях типа bullshit и тому подобному... Ссылочку сходу не приведу, но написано было смачно...
|
13 Apr 2011 09:36 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Это наверно отголоски какой-то холливор... Не люблю когда ругают языки программирования.
Они всёж сделаны людьми и для людей.
Другое дело, что в большинстве они имеют некую направленность, но в принципе
на всём можно написать всё.
А всёж интересно было бы ссылочку глянуть. Читал я, что Linus Torvalds
высказался в том плане, что человек он обеспеченный и ему на многое плевать...
А тут...
|
13 Apr 2011 09:45 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Не это ли??? (Нарыл по Гуглю: Linus Torvalds C++ bullshit)
| | | | Linus Torvalds on C++ wrote: *YOU* are full of bullshit.
C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles Bader jokingly said "to piss you off", but it's actually true. I've come to the conclusion that any programmer that would prefer the project to be in C++ over C is likely a programmer that I really *would* prefer to piss off, so that he doesn't come and screw up any project I'm involved with.
C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:
- infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)
- inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C. And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap.
So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake. The fact that we also piss off people who cannot see that is just a big additional advantage.
If you want a VCS that is written in C++, go play with Monotone. Really. They use a "real database". They use "nice object-oriented libraries". They use "nice C++ abstractions". And quite frankly, as a result of all these design decisions that sound so appealing to some CS people, the end result is a horrible and unmaintainable mess.
But I'm sure you'd like it more than git.
Linus
| | | | |
http://harmful.cat-v.org/software/c++/linus
Довольно давнее сообщение: Date: 2007-09-06 17:50:28 GMT
Кто-бы перевёл... весьма специфичный на разные "термины" текст...
|
13 Apr 2011 09:59 |
|
|
Who is online |
Users browsing this forum: No registered users and 2 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
|
|