реклама на сайте
подробности

 
 
> К знатокам, Локальные переменные.
SasaVitebsk
сообщение Sep 6 2007, 00:58
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Пишу достаточно простую прогу. Пытаюсь оптимизировать.

Столкнулся с одной бедой. Попробую описать.

Построено на прерываниях. Между прерываниями разные промежутки. Есть короткие, есть длинные. Как назло именно короткое прерывание сильно загружено. Дабы разгрузить его я пытаюсь часть вычислений вынести в предыдущее не загруженное прерывание. Уже полностью перешёл на указатели, но всё равно шляпа получается.

Проблема в том, что я не могу ввести локальные переменные на два прерывания. Таким образом я ввожу статик. Но тогда во втором прерывании компилятор пытается сохранить значения. А мне это не надо ни капельки. Чтобы этого избежать я ввёл локальные переменные и во втором прерывании выполнил присваивание локальным статик. Код получился значительно компактнее, но всё равно выполняется никому не нужное присваивание. А это 6 указателей!

Теперь сам вопрос.
Могу ли я указать компилятору что можно разрушать переменные в данном прерывании. То есть что не надо их хранить. Или как это сделать. Надо типа переобъявить статические переменные локальными. Не знаю как выразится. Надеюсь поняли.
Go to the top of the page
 
+Quote Post
9 страниц V  « < 7 8 9  
Start new topic
Ответов (120 - 132)
alexander55
сообщение Sep 28 2007, 06:00
Сообщение #121


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(dxp @ Sep 28 2007, 09:47) *
Все так. Конструкторы я тут не стал определять, т.к. мне не ясно, что они должны делать. Как и функции, которые дальше делают что-то с полученными данными. Поэтому классы и не полные.

Я это понял. smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2007, 07:49
Сообщение #122


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alexander55 @ Sep 28 2007, 07:53) *
Конструкторы позволяют всю инициализацию убрать в классы.
При этом получается следующие плюсы C++:
-отсутствие бесчисленной инициализации в main;
Все в этом хорошо кроме двух существенных недостатков - в конструкторах нельзя использовать сервисы ОС, ибо ос запускается из main() и второй - не гарантирован порядок вызова конструкторов. И если один объект использует при инициализации данные другого - возможны три варианта:
1) повезет и порядок случайно окажется нужным
2а) не повезет, и работать не будет,
2б) не повезет, но работать будет
3) завести в каждом классе init() и вызвать его в нужном порядке из main(), а конструктор не нужен.

Как решать такие ситуации? Объясню на двух простых примерах:
1) scmRTOS. Каждый поток в своем конструкторе прописывает себя в таблице объекта Kernel. Чаще всего объект Kernel еще не существует и спасает лишь то, что он глобальный, и его адрес известен компилятору. Потоки складывают данные туда, где потом разместится Kernel. Это случай типа 2б и спасает лишь то, что конструктор TKernel фактически разбит на две части - сначала при обнулении неинициализированных глобальных переменных обнуляется и память на месте размещения Kernel, а потом, при конструировании объекта заполняются своими значениями ненулевые члены. Здесь процесс борьбы вроде бы очевиден - поскольку ядро может быть лишь одно, то его можно сделать виртуальным базовым классом для потоков или все его(ядра) члены - статическими. Второй способ менее элегантен, ибо придется где-то отдельно перечислять инициализацию каждого члена.

2) Микросхема Wiznet. Имеет 4 сокета (каждый со своим набором регистров) и набор общих настроек. Описана классом TWiznet, который имеет членами массив из четырех TSocket. Вроде все логично.
Есть объекты (Ttelnet, Ttftp), которые используют сокеты и которые по хорошему в конструкторах должны делать настройку сокетов, но проблема в том, что на момент вызова конструкторов этих объектов объекты сокетов еще не созданы. Тупик, приводящий к варианту 3.


Для Непомнящий Евгений: Посмотрел ваш исходник, есть вопрос. Почему вы в конструкторе используете конструкцию { this->member = initvalue; } вместо рекомендуемой Страуструпом (правда он тоже не всегда ее придерживается) : member1(initvalue1) {}?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 28 2007, 08:38
Сообщение #123


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Сергей Борщ @ Sep 28 2007, 14:49) *
Как решать такие ситуации? Объясню на двух простых примерах:
1) scmRTOS. Каждый поток в своем конструкторе прописывает себя в таблице объекта Kernel. Чаще всего объект Kernel еще не существует и спасает лишь то, что он глобальный, и его адрес известен компилятору. Потоки складывают данные туда, где потом разместится Kernel. Это случай типа 2б и спасает лишь то, что конструктор TKernel фактически разбит на две части - сначала при обнулении неинициализированных глобальных переменных обнуляется и память на месте размещения Kernel, а потом, при конструировании объекта заполняются своими значениями ненулевые члены.

Оно не то, чтобы спасает, оно на этом и основано - объект Kernel размещается статически, т.е. память под него выделяется на этапе компиляции, и на рантайме туда уже писать вполне безопасно. Безотносительно к тому, инициализирована эта память или нет.

Цитата(Сергей Борщ @ Sep 28 2007, 14:49) *
2) Микросхема Wiznet. Имеет 4 сокета (каждый со своим набором регистров) и набор общих настроек. Описана классом TWiznet, который имеет членами массив из четырех TSocket. Вроде все логично.
Есть объекты (Ttelnet, Ttftp), которые используют сокеты и которые по хорошему в конструкторах должны делать настройку сокетов, но проблема в том, что на момент вызова конструкторов этих объектов объекты сокетов еще не созданы. Тупик, приводящий к варианту 3.

Есть честный обходной путь. Размещай объявления объектов в одной единице компиляции и порядок вызова конструкторов будет гарантирован. На уровне проекта это вполне нормальное и устойчивое решение.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alexander55
сообщение Sep 28 2007, 09:10
Сообщение #124


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



[quote name='Сергей Борщ' date='Sep 28 2007, 11:49' post='300070']
И если один объект использует при инициализации данные другого - возможны три варианта:
1) повезет и порядок случайно окажется нужным
2а) не повезет, и работать не будет,
2б) не повезет, но работать будет
3) завести в каждом классе init() и вызвать его в нужном порядке из main(), а конструктор не нужен.
quote]
Проблема понятная.
Возможные решения.
1. Если логично, использовать наследование (тогда порядок вызова конструкторов однозначный).
2. Использование наследования виртуальных классов.
3. В main сразу всех родить.
4. Нехороший вариант. Проверять есть ли данный класс.

По поводу scmRTOS лучше ответит Гари (я его видел мельком).
PS. Пока я ходил обедать, он уже ответил.

Сообщение отредактировал alexander55 - Sep 28 2007, 09:12
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Sep 28 2007, 09:44
Сообщение #125


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(Сергей Борщ @ Sep 28 2007, 11:49) *
Для Непомнящий Евгений: Посмотрел ваш исходник, есть вопрос. Почему вы в конструкторе используете конструкцию { this->member = initvalue; } вместо рекомендуемой Страуструпом (правда он тоже не всегда ее придерживается) : member1(initvalue1) {}?


У меня имя члена совпадает с именем аргумента, и я как-то не пробовал что получится при записи
: member1(member1) {}

Ну и как-то привычнее smile.gif. Я списки инициализации использую для конструкторов предков, объектов-членов и констант, а все остальное обычно размещаю в теле конструктора.

Сообщение отредактировал Непомнящий Евгений - Sep 28 2007, 09:48
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 28 2007, 10:30
Сообщение #126


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Непомнящий Евгений @ Sep 28 2007, 16:44) *
У меня имя члена совпадает с именем аргумента, и я как-то не пробовал что получится при записи
: member1(member1) {}

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

Цитата(Непомнящий Евгений @ Sep 28 2007, 16:44) *
Ну и как-то привычнее smile.gif. Я списки инициализации использую для конструкторов предков, объектов-членов и констант, а все остальное обычно размещаю в теле конструктора.

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2007, 20:09
Сообщение #127


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Непомнящий Евгений @ Sep 28 2007, 12:44) *
Ну и как-то привычнее smile.gif. Я списки инициализации использую для конструкторов предков, объектов-членов и констант, а все остальное обычно размещаю в теле конструктора.
Но ведь тот же Страуструп пишет, что если член будет не POD-типа, то при таком варианте для члена сначала будет вызван конструктор по умолчанию, а потом (уже в теле) копирующий конструктор. К тому же если член не имеет конструктора по умолчанию, то компилятор просто выдаст ошибку.

Правильно ли я понял, что все сводится только к эстетическим соображениям? Я пока только учусь, поэтому хочу разобраться laughing.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Sep 28 2007, 21:29
Сообщение #128


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(dxp @ Sep 22 2007, 20:52) *
Я не буду оригинальным, просто повторю, что говорят авторитетные дядьки вроде Г.Буча и Б.Страуструпа. Самое главное при объектном подходе - это сопоставлять классы и объекты объектам реального мира. Мир в восприятии человека представляется дискретным - человек выделяет в нем более-менее законченные целостные объекты, понятия, которыми он оперирует, строя модели. Так вот объектные (и объектно-ориентированные) языки позволяют на уровне средств языка оперировать типами, отображаемыми на объекты реального мира. Просто старайтесь вычленить в своей программе и прежде всего в той предметной области, которую описывает программа, эти самые законченные (на достаточном уровне абстракции, конечно) объекты и понятия, а после этого уже можно спокойно описывать эти объекты у себя в программе. Этот подход позволяет при разработке программы сразу думать на уровне объектов, а не разрозненных переменных, связи между которыми при отсутствии тех же классов разработчику приходится держать в голове. Понятно, что думать на уровне объектов реального мира намного проще, чем на уровне гораздо большего количества неких в разной мере абстрактных переменных встроенных типов.


[quote name='dxp' post='299963' date='Sep 28 2007, 08:31']
Ну, собсно, тут на плюсах особенно не развернуться, чтобы показаться во всей красе smile.gif,
Код
...........................
class TPorts
{
public:
    INLINE void read()
    {
       pinb  = PINB;       // читаем порты
       pinc  = PINC;
       pind  = PIND;
    }

private:
    byte pinb;
    byte pinc;
    byte pind;
}
ports;
[/quote]Не могли бы Вы на примере Вашего объекта ответить на несколько вопросов

Класс который вы назвали TPorts(хотя логичнее его было бы назвать TPortsBCD) это дискретный
законченный целостный объект ? (про незаконченную реализацию я уже читал...)
Если в другом проекте мне понадобятся порты С, D и E, я должен буду создавать для этого
новый класс ?
Если в другом проекте мне понадобится не 3 таких порта а например 2 или 4, я должен
создать новый класс ? (с самого начала)
Если иногда мне нужно читать пины всех портов одновременно, а иногда только пины одного
порта, я должен в этом классе предусмотреть функции для чтения каждого порта по отдельности ?
А если мне нужно еще и писать иногда в порт, причем в любой из 3 по определенным битам ?
.........................................
и т.д. .......

Для меня Ваш класс как минимум нелогичен,
ИМХО, начинать таки нужно с одного класса под названием TPort(один порт, любой).
Ваш класс, ИМХО, имеет очень маленькое отношение к ОПП, это больше похоже на
вариант "меня попросили написать с классами, я и написал".

P.S. А насчет того что развернуться негде, еще как есть...
Тока оверхеда при этом будет мама не горюй...


[quote name='dxp' post='299963' date='Sep 28 2007, 08:31']
Кстати, о кодогенерации. Вот, что получилось:
.........................
По-моему, тут и руками лучше не напишешь.  :)
[/quote]попробуйте вот так:
[code]
    INLINE void handle()
    {
                                byte tmp;
        adcl        = ADCL;      // читаем результат последнего преобразования
        adch        = ADCH;
        ADMUX       = admux;     // новый канал
                                tmp = adcsra;
        ADCSRA      = tmp;    // запускаем новое преобразование
        systickstart =  tmp;
    }

Должно слегка помочь smile.gif
И это исчо без применения асм и всяких хаков smile.gif
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Sep 29 2007, 04:14
Сообщение #129


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(singlskv @ Sep 29 2007, 01:29) *
Тока оверхеда при этом будет мама не горюй...


Мой сослуживец писал класс "Ножка порта". Использовал шаблон и инлайн-функции. Проверил результат - оверхеда нету. Потом параметризовал такими классами класс, считающий импульсы.

Единственное, что мне не нравится в таком подходе - если использовать шаблоны на низком уровне иерархии, то они "тянутся" наверх; притом реализацию функций класса-шаблона надо делать в h-файле.



Цитата(Сергей Борщ @ Sep 29 2007, 00:09) *
Но ведь тот же Страуструп пишет, что если член будет не POD-типа, то при таком варианте для члена сначала будет вызван конструктор по умолчанию, а потом (уже в теле) копирующий конструктор. К тому же если член не имеет конструктора по умолчанию, то компилятор просто выдаст ошибку.

Правильно ли я понял, что все сводится только к эстетическим соображениям? Я пока только учусь, поэтому хочу разобраться


Так я ж вроде бы и сказал, что для инициализации объектов - членов, предков и констант использую список инициализации.
Члены встроенных типов я инициализирую в теле конструктора по привычке; может стоит от нее отказаться.

Счас проверил, запись вида : member1(member1) действительно работает правильно.
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 29 2007, 07:04
Сообщение #130


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(singlskv @ Sep 29 2007, 04:29) *
Класс который вы назвали TPorts(хотя логичнее его было бы назвать TPortsBCD) это дискретный
законченный целостный объект ? (про незаконченную реализацию я уже читал...)

Как может быть незаконченный объект быть "дискретным законченным целостным" объектом? Любой объект класса дискретный по определению. Насколько он целостный, зависит от многих факторов, но как правило - это субъективная характеристика. А то, что он незаконченный, я уже сказал и объяснил почему.

Цитата(singlskv @ Sep 29 2007, 04:29) *
Если в другом проекте мне понадобятся порты С, D и E, я должен буду создавать для этого
новый класс ?
Если в другом проекте мне понадобится не 3 таких порта а например 2 или 4, я должен
создать новый класс ? (с самого начала)
Если иногда мне нужно читать пины всех портов одновременно, а иногда только пины одного
порта, я должен в этом классе предусмотреть функции для чтения каждого порта по отдельности ?
А если мне нужно еще и писать иногда в порт, причем в любой из 3 по определенным битам ?
.........................................
и т.д. .......

Это все вопросы уровня проектирования. Безусловно, я не могу написать реализацию, которая вас устроила бы, и никто не сможет, если он не телепат. Только вы сами можете это сделать. Я написал пример, основываясь на том коде, который вы привели. Что из него можно было понять? Только то, что в прерывании по системного таймеру производится чтение данных АЦП, запуск нового преобразования и чтение портов. Как между собой связаны таймер, АЦП и порты, я не знаю. Почему чтение и запуск АЦП производится в прерывании от таймера, а не в собственном, я тоже не знаю. Но не берусь давать такому подходу оценку, т.к. не знаю ни предметной предметной области, ни конкретной ситуации, для которой написана программа. Я лишь написал с помощью классов тот фрагмент, который был предложен к рассмотрению.

Но ведь исходно вопрос-то возник не из-за этих вопросов проектирования, а из-за того, что якобы, классы привносят в код оверхед сами по себе. Это нисколько не так, что приведенный пример, надеюсь, ясно продемонстрировал.

Цитата(singlskv @ Sep 29 2007, 04:29) *
Для меня Ваш класс как минимум нелогичен,
ИМХО, начинать таки нужно с одного класса под названием TPort(один порт, любой).

Это и есть проектирование программы. Вам тут безусловно виднее. Но то, что об этом заходит речь - это показывает различия в подходе при разработке программы на С и на C++. На С можно писать код, не задумываясь об этих моментах - программных сущностях, их иерархиях и взаимосвязях, - многие так и пишут, "в лоб". И, как правило, такие программы не отличаются структурной стройностью, внутренней логичностью, тяжелее в расширении и сопровождении. Конечно, можно писать на С и по-другому, разработав структуру и придерживаясь ее, но это требует известных усилий и квалификации.

С++ же напротив - тяготеет к такому стилю, при использовании классов сам подход сводится к определению нужных классов, наделения их необходимой функциональностью. А для этого надо сразу четко представлять, что мы имеем, что хотим реализовать, какие сущности у нас присутствуют в предметной области и т.д. Т.е. этап проектирования возникает сразу в явном виде на базе объектного подхода. Поскольку все эти различия идут на уровне исходного кода, кодогенерация и эффективность по сравнению с С не страдают.

Цитата(singlskv @ Sep 29 2007, 04:29) *
Ваш класс, ИМХО, имеет очень маленькое отношение к ОПП,

Он вообще к ООПу никакого отношения не имеет. biggrin.gif

Цитата(singlskv @ Sep 29 2007, 04:29) *
это больше похоже на вариант "меня попросили написать с классами, я и написал".

Почти так. Меня попросили реализацию фрагмента на С++, я ее сделал. Вы не это просили разве?

Цитата(singlskv @ Sep 29 2007, 04:29) *
P.S. А насчет того что развернуться негде, еще как есть...
Тока оверхеда при этом будет мама не горюй...

Не понял, что вы тут имели в виду. И про какой оверхед речь?

Цитата(singlskv @ Sep 29 2007, 04:29) *
попробуйте вот так:
Код
    INLINE void handle()
    {
                                byte tmp;
        adcl        = ADCL;      // читаем результат последнего преобразования
        adch        = ADCH;
        ADMUX       = admux;     // новый канал
                                tmp = adcsra;
        ADCSRA      = tmp;    // запускаем новое преобразование
        systickstart =  tmp;
    }

Должно слегка помочь smile.gif
И это исчо без применения асм и всяких хаков smile.gif

За счет чего? И причем тут уже ++?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
singlskv
сообщение Sep 29 2007, 19:59
Сообщение #131


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(dxp @ Sep 29 2007, 11:04) *
Почему чтение и запуск АЦП производится в прерывании от таймера, а не в собственном, я тоже не знаю. Но не берусь давать такому подходу оценку, т.к. не знаю ни предметной предметной области, ни конкретной ситуации, для которой написана программа.
Дык ответ то прост и банален, потому что джиттера не будет smile.gif при чтении портов например...
Цитата
Я лишь написал с помощью классов тот фрагмент, который был предложен к рассмотрению.

Цитата
Но ведь исходно вопрос-то возник не из-за этих вопросов проектирования, а из-за того, что якобы, классы привносят в код оверхед сами по себе. Это нисколько не так, что приведенный пример, надеюсь, ясно продемонстрировал.
dxp, я надеюсь что Вы сами то понимаете что слегка лукавите ?
Вариант классы ради классов я все-таки не рассматривал.
Вы будете меня убеждать что класс подобный описанному Вами будет когда-либо присутствовать
в Вашей программе ? (лучше соврите если это правда smile.gif )
Цитата
С++ же напротив - тяготеет к такому стилю, при использовании классов сам подход сводится к определению нужных классов, наделения их необходимой функциональностью. А для этого надо сразу четко представлять, что мы имеем, что хотим реализовать, какие сущности у нас присутствуют в предметной области и т.д.
И эта функциональность бывает иногда(часто) излишней для конкретного проекта.
Заметим сразу же что если какая-то функция реализованна в классе, то линкер не
имеет возможности выкинуть эту функцию из конечного бинарника(или имеет такое право...,
засомневался, кто знает просветите...)
Цитата
Он вообще к ООПу никакого отношения не имеет. biggrin.gif
Почти так. Меня попросили реализацию фрагмента на С++, я ее сделал. Вы не это просили разве?
Повторюсь еще раз, классы ради классов... smile.gif
Цитата
Не понял, что вы тут имели в виду. И про какой оверхед речь?
Все очень просто,
Вы создаете реальный(похожий на реальность) класс под названием типа TPort.
Этот объект будет включать в себя переменную указывающую на адрес
регистра PINx(в общем случае там таких переменных будет 3 (pin, port и ddr), хотя
в частных реализациях можно обойтись и одним адресом).
Так же в этом классе будет реализован доступ к этому порту в разных вариантах,
типа считать, записать, считать с маской, записать с маской, и т.д.
ну и конечно конструктор с привязкой к конкретному порту.
Про оверхед нужно объяснять или сами все поняли ?
Цитата
И причем тут уже ++?
С++ здесь уже действительно не при чем.
Цитата
За счет чего?
Ну это вроде очивидно,
за счет исключения лишнего считывания adcsra из памяти.
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 30 2007, 11:12
Сообщение #132


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(singlskv @ Sep 30 2007, 02:59) *
dxp, я надеюсь что Вы сами то понимаете что слегка лукавите ?
Вариант классы ради классов я все-таки не рассматривал.
Вы будете меня убеждать что класс подобный описанному Вами будет когда-либо присутствовать
в Вашей программе ? (лучше соврите если это правда smile.gif )

Не понимаю, где я дал основание подозревать меня во вранье? Подобные мелкие классы я использовал и использую в своих программах, т.к. не вижу тому препятствий. Удобство же налицо - логическое объединение кода в отдельное пространство имен с возможностью управления доступом. Если вам это не надо, это не причина для обвинений во лжи.

Цитата(singlskv @ Sep 30 2007, 02:59) *
И эта функциональность бывает иногда(часто) излишней для конкретного проекта.
Заметим сразу же что если какая-то функция реализованна в классе, то линкер не
имеет возможности выкинуть эту функцию из конечного бинарника(или имеет такое право...,
засомневался, кто знает просветите...)

А почему не имеет? Что мешает? Функция-член класса ничем особенным в бинарнике не отличается. Вот если это виртуальная функция, то ее выкинуть нельзя, т.к. ее адрес помещается в vtbl. Но и на С если есть массив указателей на функции, то все функции будут включены, даже если какие-то из них не используются.

Цитата(singlskv @ Sep 30 2007, 02:59) *
Повторюсь еще раз, классы ради классов... smile.gif

Классы ради удобства логического представления.


Цитата(singlskv @ Sep 30 2007, 02:59) *
Все очень просто,
Вы создаете реальный(похожий на реальность) класс под названием типа TPort.
Этот объект будет включать в себя переменную указывающую на адрес
регистра PINx(в общем случае там таких переменных будет 3 (pin, port и ddr), хотя
в частных реализациях можно обойтись и одним адресом).
Так же в этом классе будет реализован доступ к этому порту в разных вариантах,
типа считать, записать, считать с маской, записать с маской, и т.д.
ну и конечно конструктор с привязкой к конкретному порту.

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

Цитата(singlskv @ Sep 30 2007, 02:59) *
Про оверхед нужно объяснять или сами все поняли ?

См выше. Кроме того, оверхед зависит от целевого процессора. Например, на MSP430 оверхеда не будет.

Цитата(singlskv @ Sep 30 2007, 02:59) *
Ну это вроде очивидно,
за счет исключения лишнего считывания adcsra из памяти.

Если вы заметили, у меня там представление класса объявлено без квалификаторов volatile, поэтому компилятору ничего не мешает оптимизировать доступ и не читать два раза. То, что он этого не сделал - это вопрос к качеству кодогенерации данного компилятора. А использовать временную переменную - это заниматься низкоуровневой оптимизацией на высоком уровне, что попахивает опять же хаком, хотя и безобидным в данном случае (из минусов то, что на пустом месте загромождается код). По правильному бороться с этим недостатком компилятора надо путем написания репорта в саппорт, чтобы этот момент в будущих версиях пофиксили.

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 30 2007, 19:35
Сообщение #133


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(dxp @ Sep 30 2007, 14:12) *
Поэтому, дабы прекратить переливание из пустого в порожнее, наверное, буду сворачивать свое участие в теме в этом контексте.


Тем не менее спасибо за полезную информацию. Несмотря на то, что получилось что-то вроде спора людей с разными взглядами, надо учесть то что некоторые не вступали в дискуссию, так как не имели знаний и опыта применения. Но при этом читали её и пытались делать свои выводы. smile.gif

С этой точки зрения, как мне кажется, дискуссия была очень полезна.
Go to the top of the page
 
+Quote Post

9 страниц V  « < 7 8 9
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 03:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01565 секунд с 7
ELECTRONIX ©2004-2016