Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Как упростить код С++ и сделать более понятным? (число прочтений - 10565 )
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Как упростить код С++ и сделать более понятным?
27. Февраля 2008 :: 09:11
Печать  
Народ, руки давно чешутся каким-то отрефакторить/упростить код наподобие следующего:
в ComponentClass.cpp
Код
Выбрать все
int  CComponentClass::КакойТоМетод(int iMethodNum, Параметры...)
{
    iMet = defFnNames->Size();
  if (iMethodNum >= iMet)
  {
    CONST_ITER_CONT iEnd(vecOfBaseCont.end());
	  for (CONST_ITER_CONT iter = vecOfBaseCont.begin(); iter != iEnd; ++iter)
    {
	CBLContext *pCont = *iter;
	int nNMethods = pCont->GetNMethods();
	if (iMethodNum < iMet+nNMethods)
	{
	  int nMeth = iMethodNum - iMet;
	  вызов соответствующего метода для pCont с передачей параметров!!
	}
	iMet += nNMethods;
    }
    return 0;
  }
  else
    return Вызов родного метода ;
}
 



И такого кода в этом файле полно.
Как думаете, каким образом можно его отрефакторить?

Например, из-за дублирования подобного кода была допущена не одна ошибка при реализации ООП.
Последняя из обнаруженных - http://www.1cpp.ru/forum/YaBB.pl?num=1204027528/0
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #1 - 27. Февраля 2008 :: 14:04
Печать  
может буду банален, но for_each() и функциональный объект.
  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #2 - 27. Февраля 2008 :: 14:06
Печать  
Думал над этим вариантом, но останавливает необходимость на каждый подобный цикл/метод делать по одной функции или функциональному объекту.
Скорее всего, иного выхода и нет Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #3 - 27. Февраля 2008 :: 14:11
Печать  
банда четырех подвела эту проблему под патерн "посетитель", если я не ошибаюсь, по младости лет..
  
Наверх
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #4 - 27. Февраля 2008 :: 14:17
Печать  
По "посетителю" нужно подумать, но больше похоже на "стратегию" ИМХО Улыбка
Хотя они оба вроде бы довольно взаимозаменяемы.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #5 - 27. Февраля 2008 :: 14:19
Печать  
Еще нужно учесть, что внутри цикла может быть и break после обработки одного из предков Улыбка для некоторых методов типа CallMethod
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #6 - 27. Февраля 2008 :: 14:34
Печать  
artbear писал(а) 27. Февраля 2008 :: 14:17:
По "посетителю" нужно подумать, но больше похоже на "стратегию" ИМХО Улыбка
Хотя они оба вроде бы довольно взаимозаменяемы.

Я пока путаюсь  Смущённый
не переварилось...
  
Наверх
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #7 - 27. Февраля 2008 :: 14:39
Печать  
ОФФ. Попробуй еще найти "Рефакторинг" Мартина Фаулера
или его же "Шаблоны корпоративных приложений" - точное название не помню, но все указанные слова в нем есть Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #8 - 28. Февраля 2008 :: 04:30
Печать  
artbear писал(а) 27. Февраля 2008 :: 09:11:
Народ, руки давно чешутся каким-то отрефакторить/упростить код наподобие следующего:
в ComponentClass.cpp


Например, можно использовать шаблоны. Для функционала обхода объектов заводим шаблонную функцию:
Код
Выбрать все
template<class Functor_t, class FunctorSelf_t>int  CComponentClass::CallMethod(int iMethodNum, Functor_t const &Func, FunctorSelf_t const &Self)
{
    iMet = defFnNames->Size();
  if (iMethodNum >= iMet)
  {
    CONST_ITER_CONT iEnd(vecOfBaseCont.end());
	  for (CONST_ITER_CONT iter = vecOfBaseCont.begin(); iter != iEnd; ++iter)
    {
	CBLContext *pCont = *iter;
	int nNMethods = pCont->GetNMethods();
	if (iMethodNum < iMet+nNMethods)
	{
	  int nMeth = iMethodNum - iMet;
	  return Func (pCont, nMeth);
	}
	iMet += nNMethods;
    }
    return 0;
  }
  else
    return Self (iMethodNum);
}
 



Тогда метод "КакойТоМетод" выглядит так:
Код
Выбрать все
int  CComponentClass::КакойТоМетод(int iMethodNum, Параметры...)
{
     return CallMethod (
	    boost::bind (&CBLContext::КакойТоМетод, _1, _2, Параметры...),
	    boost::bind (&CComponentClass::КакойТоМетодОбработчик, this, _1, Параметры...));
}
 



Проблемы тут, в общем-то, две:
1) VC6. Как этот недокомпилятор сможет такое переварить - неизвестно. Хотя boost::bind вроде бы работает в VC6. Впрочем, на крайний случай всегда можно будет написать свой функтор.
2) При создании функторов при помощи boost::bind всегда будут инициализироваться оба функтора (в каждый из них будут копироваться параметры и т.д.). Впрочем, если CallMethod полностью заинлайнится, накладных расходов не будет. В IC, скорее всего, так и будет. Что будет в VC6 - тайна покрытая мраком.
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #9 - 28. Февраля 2008 :: 05:15
Печать  
Uzhast писал(а) 28. Февраля 2008 :: 04:30:
Код
Выбрать все
boost::bind (... _1, _2...)
 


Хотелось бы про лямбда-функции послушать лекцию  Подмигивание
  
Наверх
ICQ  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Как упростить код С++ и сделать более понятным
Ответ #10 - 28. Февраля 2008 :: 06:11
Печать  
Uzhast

Ты еще не проводил исследований на предмет, как инлайнятся адаптеры, и как чистые функторы?
Как ведет себя mem_fun и т.п. мне понятно, а вот с boost::bind - не смотрел.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #11 - 28. Февраля 2008 :: 06:38
Печать  
spock писал(а) 28. Февраля 2008 :: 05:15:
Хотелось бы про лямбда-функции послушать лекцию  Подмигивание

Наличие в коде символов _1, _2 и т.п. еще не означает, что используются лямбда-функции. Лямбда - это определение функции по месту использования. Например:

Найти первый элемент, меньший 2:
Код
Выбрать все
std::find_if (Cont.begin (), Cont.end (), _1 < 2);
 



В моем примере используется простой boost::bind - это не лямбда, а просто адаптер функции. Фактически это конвертер одного интерфейса вызова в другой интерфейс вызова. И все. Про bind здесь можно почитать: http://rsdn.ru/article/cpp/boost.bind.xml
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #12 - 28. Февраля 2008 :: 06:43
Печать  
kms писал(а) 28. Февраля 2008 :: 06:11:
Uzhast

Ты еще не проводил исследований на предмет, как инлайнятся адаптеры, и как чистые функторы?
Как ведет себя mem_fun и т.п. мне понятно, а вот с boost::bind - не смотрел.

Если вызывается адаптер для адреса функции то я наблюдал два варианта:
1) косвенный вызов
2) прямой вызов - косвенный вызов был устранен.
Инлайна не наблюдал. Но, может, и бывает Улыбка

Попробовал функторы. У меня таких вызовов с bind'ом практически нет. Для тех, что есть, инлайна не случилось. Компилятор только убрал косвенный вызов - оставил прямой вызов operator ().
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #13 - 28. Февраля 2008 :: 06:47
Печать  
Ну и, когда я говорю про инлайн, я имею в виду инлайн тех функций, что нужно адаптировать. Код же самого функтора, который порождает boost::bind полностью проинлайнился Улыбка Т.е. никаких левых вызовов, кроме вызова привязанной функции, нет.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #14 - 28. Февраля 2008 :: 06:56
Печать  
Uzhast писал(а) 28. Февраля 2008 :: 06:43:
Если вызывается адаптер для адреса функции то я наблюдал два варианта:
1) косвенный вызов
2) прямой вызов - косвенный вызов был устранен.
Инлайна не наблюдал. Но, может, и бывает Улыбка

Поделись еще - каким образом наблюдал?
Смотрел скомпилированный код ассемблера или еще как?
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #15 - 28. Февраля 2008 :: 06:59
Печать  
artbear писал(а) 28. Февраля 2008 :: 06:56:
Поделись еще - каким образом наблюдал?
Смотрел скомпилированный код ассемблера или еще как?

Включил генерацию ASM-файла. У IC это тоже есть Улыбка
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #16 - 28. Февраля 2008 :: 07:08
Печать  
Uzhast писал(а) 28. Февраля 2008 :: 06:47:
Ну и, когда я говорю про инлайн, я имею в виду инлайн тех функций, что нужно адаптировать. Код же самого функтора, который порождает boost::bind полностью проинлайнился Улыбка Т.е. никаких левых вызовов, кроме вызова привязанной функции, нет.

Думаю, даже, если в VC6 не будет полного инлайна Печаль, в этом нет ничего страшного, один косвенный вызов не страшен.
Зато код будет очень красивым.

ЗЫ все равно давно хотел с bind потренироваться Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #17 - 28. Февраля 2008 :: 07:13
Печать  
artbear писал(а) 28. Февраля 2008 :: 07:08:
Думаю, даже, если в VC6 не будет полного инлайна Печаль, в этом нет ничего страшного, один косвенный вызов не страшен.
Зато код будет очень красивым.

Хотя точный диагноз потерь производительности даст, конечно, только профайлер.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #18 - 28. Февраля 2008 :: 13:48
Печать  
Uzhast писал(а) 28. Февраля 2008 :: 06:38:
Про bind здесь можно почитать: http://rsdn.ru/article/cpp/boost.bind.xml

хорошая статья, спасибо
  
Наверх
ICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #19 - 28. Февраля 2008 :: 15:48
Печать  
artbear писал(а) 27. Февраля 2008 :: 14:39:
ОФФ. Попробуй еще найти "Рефакторинг" Мартина Фаулера
или его же "Шаблоны корпоративных приложений" - точное название не помню, но все указанные слова в нем есть Улыбка

нашел.
http://www.proklondike.com/contentview.php?content=258
  
Наверх
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Как упростить код С++ и сделать более понятным
Ответ #20 - 29. Февраля 2008 :: 09:32
Печать  
spock писал(а) 28. Февраля 2008 :: 13:48:
Uzhast писал(а) 28. Февраля 2008 :: 06:38:
Про bind здесь можно почитать: http://rsdn.ru/article/cpp/boost.bind.xml

хорошая статья, спасибо

Статья хорошая, сортировка плохая.

Uzhast

Если еще че стоящего по Boost найдешь, делись, интересно.

Отсюда можно быстро в цифрах оценить разницу между чистым функтором и адаптером (и не только):
http://rsdn.ru/article/devtools/CppPerformance.xml

А это здесь не в тему, но создавать новую тему в лом:
http://rsdn.ru/Forum/Info/FAQ.cpp.stl.speed.aspx

Что Павел за человек? Как это читать? Где версии нах?
И все равно интересно, перевел для десятки в xls.
  

10000.xls ( 22 KB | Загрузки )

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #21 - 01. Марта 2008 :: 10:29
Печать  
kms писал(а) 29. Февраля 2008 :: 09:32:
Отсюда можно быстро в цифрах оценить разницу между чистым функтором и адаптером (и не только):
http://rsdn.ru/article/devtools/CppPerformance.xml

Эту статью в комментах покритиковали довольно справедливо. (Или не в комментах?... В общем, была ветка в rsdn.cpp) Но все равно довольно интересно. Улыбка

kms писал(а) 29. Февраля 2008 :: 09:32:
А это здесь не в тему, но создавать новую тему в лом:
http://rsdn.ru/Forum/Info/FAQ.cpp.stl.speed.aspx

Что Павел за человек? Как это читать? Где версии нах?
И все равно интересно, перевел для десятки в xls.

Ну, это сначала было не статьей, а просто постом в форуме, где он просто показал результаты тестов с последними на тот момент версиями Улыбка

А это ты удачно в Excel все завернул - наглядно получилось Улыбка Забавно, что STLport почти всегда впереди. Правда, у него свой аллокатор вроде бы - за счет этого он и выигрывает. Поговаривают, что если к dinkum присобачить более шустрый аллокатор, то он тоже не таким уж черепашистым становится Улыбка
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #22 - 12. Марта 2008 :: 13:49
Печать  
trdm писал(а) 28. Февраля 2008 :: 15:48:
artbear писал(а) 27. Февраля 2008 :: 14:39:
ОФФ. Попробуй еще найти "Рефакторинг" Мартина Фаулера
или его же "Шаблоны корпоративных приложений" - точное название не помню, но все указанные слова в нем есть Улыбка

нашел.
http://www.proklondike.com/contentview.php?content=258

Вот точное название
Мартин Фаулер - Архитектура корпоративных программных приложений
Если найдешь в электронном виде, пиши. Самому нужна Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #23 - 12. Марта 2008 :: 14:11
Печать  
artbear писал(а) 12. Марта 2008 :: 13:49:
Вот точное название
Мартин Фаулер - Архитектура корпоративных программных приложений
Если найдешь в электронном виде, пиши. Самому нужна Улыбка

тынц?
  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как упростить код С++ и сделать более понятным
Ответ #24 - 13. Марта 2008 :: 22:17
Печать  
trdm писал(а) 12. Марта 2008 :: 14:11:
artbear писал(а) 12. Марта 2008 :: 13:49:
Вот точное название
Мартин Фаулер - Архитектура корпоративных программных приложений
Если найдешь в электронном виде, пиши. Самому нужна Улыбка

тынц?

не понравилась книжка.... (
  
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать