Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Как упростить код С++ и сделать более понятным? (число прочтений - 9784 )
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
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 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
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 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 записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать