|
инкапсуляция в С, как? |
|
|
|
Apr 18 2014, 12:17
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(aaarrr @ Apr 18 2014, 16:06)  Сначала надо определиться, что именно здесь некрасиво и неправильно. Я, например, не вижу проблем. проблема в том, что буфер объявлен как глобальный в одном модуле proc.c, а в другом модуле main.c происходит его чтение, и там он объявлен как extern buf ну и собственно глобальные переменные - это не правильно. Разве нет?
|
|
|
|
|
Apr 18 2014, 15:40
|

Группа: Участник
Сообщений: 6
Регистрация: 20-04-13
Пользователь №: 76 551

|
Это увеличивает связность кода и соответственно усложняет его понимание. Как по мне так лучше в одном файле обьявить static array. И написать функции работы с ним (чтение и запись), которые будут видны в других файлах. Так гораздо удобнее отлавливать баги связанные с массивом, и проще понять где было произведено чтение или модификация массива.
|
|
|
|
|
Apr 18 2014, 16:33
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(Dubov @ Apr 18 2014, 16:01)  Хочется писать красивый и правильный код. Сейчас активно использую глобальные переменные и типа, если надо чтобы один модуль записывал данные, а другой их читал, то объявляю буфер как extern buf[256]; Если надо красиво и правильно, но все объявления extern-объектов следует делать в отдельном хидере. Например, в global.h куда вписать все extern-определения. А чтобы и сами глобальные объекты не расползлись по разным модулям, то их желательно тоже поместить в отдельную корзину. Например, собрать их всех в модуле global.c или завести себе правило объявлять глобальные переменные только в модуле main.c (тогда и global.h можно обозвать main.h). А в самих сишных модулях слово extern никогда (!) не должно встречаться, а допустимо лишь включать #include "global.h" или #include "main.h" Тогда уж вы точно избежите любых ошибок, связанных с недоопределением глобальных переменных.
|
|
|
|
|
Apr 18 2014, 23:36
|

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

|
Цитата(Xenia @ Apr 19 2014, 01:13)  Именно так. Определения, которые используются более чем одним модулем, должны не повторяться в каждом модуле, а быть однократно определены в хидере. А вот и нет. Во-первых не определения, а объявления. А во-вторых переменные модуля А и его функции, которые используются другими модулями, должны быть объявлены в его заголовочном файле A.h и именно этот заголовочный файл должен включаться в тот и только в тот исходник/заголовочный файл, где эти объявления используются. А валить все в одну кучу, в один глобальный файл - это кошмар для сопровождения проекта.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 19 2014, 03:39
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(Сергей Борщ @ Apr 19 2014, 03:36)  А вот и нет. Во-первых не определения, а объявления. Ну, путь объявления. Цитата(Сергей Борщ @ Apr 19 2014, 03:36)  А во-вторых переменные модуля А и его функции, которые используются другими модулями, должны быть объявлены в его заголовочном файле A.h и именно этот заголовочный файл должен включаться в тот и только в тот исходник/заголовочный файл, где эти объявления используются. А валить все в одну кучу, в один глобальный файл - это кошмар для сопровождения проекта. A.h это само собой. Ничто не мешает каждому модулю иметь свой хидер, в котором объявлять те функции, которые в нем определяются. А хидер global.h подключается дополнительно. Ведь и без того одним хидер-файлом не обойдешься.
|
|
|
|
|
Apr 19 2014, 07:31
|

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

|
Цитата(Xenia @ Apr 19 2014, 06:39)  А хидер global.h подключается дополнительно. Ведь и без того одним хидер-файлом не обойдешься. Зачем, ну объясните мне, зачем делать эту общую свалку global.h? Только ради того, чтобы в каждом исходнике писать одну строчку #include "global.h" вместо нескольких, по которым будет совершенно однозначно видно, какие именно другие модули использует этот? И какие файлы надо захватить вместе с этим при копировании этого модуля в другой проект? И что-то я не понял насчет "подключается дополнительно". Если уже подключен заголовочный файл модуля А.h, то включены все необходимые объявления модуля A. Что тогда будет в global.h?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 19 2014, 09:32
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(=AK= @ Apr 19 2014, 07:34)  Такой подход имеет право на существование, однако у него все же есть два недостатка: - Пространство имен функций все-таки засоряется. Не получится иметь 100500 функций init(); - На вызов функции и возврат из нее тратится время и память кода. Напрямую с переменной работать эффективнее. Со временем устаканилось две вещи (как ответ на "два недостатка"): 1. Там, где надо 100500 ИНИТов делать - это решается через хэндлы. Как говорят военные, безобразно, зато единообразно. Код struct _handle { void (*init)(void); void (*done)(void); }; 2. Там, где требуется оченно зашкаливающая эффективность, - там нет таких объемов данных и все сосредоточено в пределах одного модуля. Это все фигня, потому что С++ все-таки дает неквадратные колеса. Если человеку аж чешется ООП, то для чего этим страдать на Си? На Си даже try - catch можно делать, ну и? На GCC можно даже частично RTTI на макросах делать. Но к чему?
Сообщение отредактировал _Pasha - Apr 19 2014, 09:38
|
|
|
|
|
Apr 20 2014, 15:50
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Цитата Зачем, ну объясните мне, зачем делать эту общую свалку global.h? Чтобы пихать туда вещи, которые не принадлежат ни к одному модулю. Глобальные переменные например. В глобально доступных переменных нет сильно большого криминала до тех пор, пока к ним доступ осуществляется атомарно в многопоточных программах. И пока не страдает логика приложения, например всё приложение начинает управляться глобальными флагами.
|
|
|
|
|
Apr 22 2014, 05:32
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(andrewlekar @ Apr 20 2014, 19:50)  Чтобы пихать туда вещи, которые не принадлежат ни к одному модулю. Глобальные переменные например. В глобально доступных переменных нет сильно большого криминала до тех пор, пока к ним доступ осуществляется атомарно в многопоточных программах. И пока не страдает логика приложения, например всё приложение начинает управляться глобальными флагами. Вот и я о том. когда всё приложение сводится к while(1) и опросу глобальных флагов if (x == 1) то это не хорошо как избежать?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|