LINUX.ORG.RU

в целях обучения C++


0

0

посоветуйте пожалуйста исходники какой прикладной программы на С++ можно было бы расковырять на предмет "так надо писать!", хотелось бы увидеть исключения, большую и хорошо организованную внутреннюю структуру, лучше, если программа каким-нибудь образом относилась к десктопу или к работе с сетью, узкоспециализированную не советуйте, мне важно понимать, что делает программа. спасибо большое!

anonymous

Ответ на: комментарий от klalafuda

Можно почитать "Практику программирования" Ритчи, чтобы понять основные принципы, но правда там речь идёт о С.

UVV ★★★★★
()
Ответ на: комментарий от anonymous

> Библиотеку Qt и ее демки поковыряй

Qt вещь хорошая ровно до тех пор, пока в силу каких-то причин не приходится лазить к ней в исходники. после этого вся хорошесть Qt быстро улетучивается.

ps: впрочем, нужно отдать должное разработчикам и документерам Trolltech, лазить внутрь Qt мне приходилось разве что из любопытства но не в силу производственных нужд.

// wbr

klalafuda ★☆☆
()

> большую и хорошо организованную внутреннюю структуру

ИМХО, ни одна большая программа не обладает "хорошо организованной внутренней структурой"

> узкоспециализированную не советуйте

все программы - узкоспециализированные :D

monotone посмотри.

В KDE есть куча программ разного размера.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> monotone посмотри.

навскидку:

--- cmd_automate.cc ---
using std::istream;
using std::make_pair;
using std::map;
using std::ostream;
using std::pair;
using std::string;
using std::vector;
......
    do
      {
        if (read(&c, 1, true) == 0)
          {
            loc = eof;
            return;
          }
      }
    while (whitespace.find(c) != std::string::npos);
    switch (c)
      {
      case 'o': loc = opt; break;
      case 'l': loc = cmd; break;
      default:
        E(false, 
            F("Bad input to automate stdio: unknown start token '%c'") % c);
      }
--- cmd_automate.cc ---

ну-ну....

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> ну-ну....

И что криминального? Или много стандартных библиртек умеют разбирать stdin с целью выделения команд и опций? Мне только shell приходит на ум.

Да и вообще: cmd_automate.cc - это не показатель :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> И что криминального? Или много стандартных библиртек умеют разбирать stdin с целью выделения команд и опций? Мне только shell приходит на ум.

за using std::... можно сразу расстреливать на месте без суда и следствия в полевых условиях. так же как и за принятое в проекте форматирование.

> Да и вообще: cmd_automate.cc - это не показатель :)

а что показатель?

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> за using std::... можно сразу расстреливать на месте без суда и следствия в полевых условиях.

Сурово у вас в Сибири :D За чЬто расстреливать-то?

> так же как и за принятое в проекте форматирование.

Я хоть и не люблю GNU indentation style, но не готов расстреливать разработчиков GCC, Emacs и еще много чего :D

Других претензий нет?

>> Да и вообще: cmd_automate.cc - это не показатель :)

> а что показатель?

Да почти всё остальное... cset.cc diff_patch.cc revision.cc roster*.cc

Другое дело, что там головоломные алгоритмы, в которых никто не разбирается, кроме njs :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Сурово у вас в Сибири :D За чЬто расстреливать-то?

за некорректное использование инструмента пространства имен.

> Я хоть и не люблю GNU indentation style, но не готов расстреливать разработчиков GCC, Emacs и еще много чего :D

мне вообщем-то по-барабану, что они ешё написали. если я считаю, что код - говно, то он не перестает быть оным лишь от того, что его сотворил кто-то там "из корифеев" или, тем более, я сам. равно как и аргументы "ну он же вроде работает... :-?" к рассмотрению не принимаются. мы рассматриваем код, а не конечный продукт который уже собственно и работает aka удовлетворяет потребности конечных пользователей.

> Да почти всё остальное... cset.cc diff_patch.cc revision.cc roster*.cc

я уже стер архив с и перекачивать его взад для дальнейшей сверки мне не хочется. охотно допускаю, что в проекте есть и другие, более вменяемые места.

> Другое дело, что там головоломные алгоритмы, в которых никто не разбирается, кроме njs :)

алгоритмы нужно изучать по хорошим книгам, а не по чужому коду.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

>за using std::... можно сразу расстреливать на месте без суда и следствия

если вы скажете как с вашей точки зрения верно, возможно я покажу вам в чем вы неправы...

aydef
()
Ответ на: комментарий от klalafuda

>> Сурово у вас в Сибири :D За чЬто расстреливать-то?

> за некорректное использование инструмента пространства имен.

В чем некорректность?

>> Я хоть и не люблю GNU indentation style, но не готов расстреливать разработчиков GCC, Emacs и еще много чего :D

>мне вообщем-то по-барабану, что они ешё написали. если я считаю, что код - говно

Код говно из-за используемого в нем стиля отступов?

> алгоритмы нужно изучать по хорошим книгам, а не по чужому коду.

Этих алгоритмов нет в книгах. Умение понять алгоритм из реализующего его кода - необходимо. Хотя пойнт не в этом...

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Код не становится говном из-за того, что какой-то klalafuda так считает. Пусть приведет пример как надо было написать. Там и посмотрим насколько к его мнению стоит прислушиваться.

anonymous
()

По теме. Попробуйте глянуть в сторону PSI. Там и структура вменяемая, и работа с сетью есть, и не полностью на Qt всё написано.

troorl ★★
()
Ответ на: комментарий от anonymous

дело в том, что люди, называющие код говном, к опенсорс имеют отношение постольку-поскольку, и, как правило, вообще ничего не написали для себя/сообщества. Конечно, их знания, зачастую весьма глубокие, никто не оспаривает, но и им не даёт права разглагольствовать направо и налево о качестве кода.

alex_custov ★★★★★
()
Ответ на: комментарий от tailgunner

>В чем некорректность?

+= 2 :)

Стиль отступов самый лучший и легкочитаемый :Р

anonymous
()
Ответ на: комментарий от alex_custov

> дело в том, что люди, называющие код говном, к опенсорс имеют отношение постольку-поскольку, и, как правило, вообще ничего не написали для себя/сообщества. Конечно, их знания, зачастую весьма глубокие, никто не оспаривает, но и им не даёт права разглагольствовать направо и налево о качестве кода.

мсье профессиональный юрист и будет объяснять мне мои права?
очень интересно послушать, честное слово.
продолжайте пожалуйста, я весь внимания.

так что вы можете сказать мне про моё право выражать своё мнение? налево и направо.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

>klalafuda (*) (09.04.2007 22:16:58)

А по теме есть что сказать?

>>В чем некорректность?

anonymous
()
Ответ на: комментарий от klalafuda

>>так что вы можете сказать мне про моё право выражать своё мнение? налево и направо.

Мне глубоко всё равно, что ты там и где будешь выражать. Я только констатирую факт. Таких людей как ты постоянно просишь дать ссылки на OS проекты, в которых они принимают участие, а в ответ - тишина. Зато разглагольствований про говёный код других проектов - предостаточно.

alex_custov ★★★★★
()
Ответ на: комментарий от smh

imo из-за большой вероятности конфликта имен. В более-менее сложной программе испольузется несколько сторонних библиотек + кучка собственных классов. А в std определяется много разных классов/шаблонов/алгоритмов с общеупотребительными именами типа string, map, set, etc

cobold ★★★★★
()
Ответ на: комментарий от smh

>> за using std::... можно сразу расстреливать на месте без суда и следствия в полевых условиях.

> почему?

потенциальные скрытые конфликты имен и, как следствие, сложность в
сопровождении проекта.

допустим, когда-то давно хакер Вася написал такой вот код:

--- foo.cc ---
#include <iostream>
#include "lib.h"

using namespace a;

class test {
public :
    test() {
        std::cout << "foo is " << foo() << std::endl;
    }
};

int
main()
{
    test test;

    return 0;
}
--- foo.cc ---

в своем проекте Вася решил использовать функцию foo из сторонней
библиотеки a. разработчики библиотеки позаботились о чистоте
глобального пространства имен и вынесли свой интерфейс в отдельное
пространство a:

--- lib.h ---
#ifndef _LIB_H_
#define _LIB_H_

namespace a {
    char foo() {
        return 'a';
    }
};

#endif // !_LIB_H_
--- lib.h ---

но Вася, будучи тру-хакером, решил, что ему впадлу каждый раз явно
указывать пространство через a:: - это целых три символа! -  и решил,
что using namespace вполне хватит.

$ ./foo
foo is a

и его действительно хватило и все нормально работало до тех пор,
пока через год в класс foo не пришлось добавить кой-чего. хакера
Васи уже и след давно простыл so для сего действа был привлечен
хакер Петя. последний не знал всех перепетий разработки класса foo
да и времени в этом разбираться было не особо много. по сему,
Петя без всякой задней мысли поменял класс foo как:

--- foo.cc ---
class test {
public :
    test() {
        std::cout << "foo is " << foo() << std::endl;
    }

private :
    char foo() {
        return 'c';
    }
};
--- foo.cc ---

после Петя успешно пересобрал проект, как-то проверил и сдал.
и лишь гораздо позже оказалось, что после Петеных изменений
что-то поменялось в поведении продукта:

$ ./foo
foo is c

...хотя проект успешно собирается и проходит какие ни есть но тесты.

приведенный пример чрезвычайно упрощен. в реальной жизни система
может быть на многие порядки сложнее и разлапистее, содержать массу
своих и сторонних модулей, не поддаваться простому модульному тестированию а Вась и Петь может быть сотни. и использовать в такой
системе упрощения типа "using" - это ламерство чистой воды. выгода
от такого упрощения ничтожна, а вот возможные последствия могут быть
более чем серьезными.

думаю, идея понятна.

ps: да, и аргументы вида "я сам тут все контролирую!" и иже с ними
категорически не принимаются. это как ходить в туалет и писать мимо
унитаза аргументируя "ну это же только дома, а в гостях - никогда!
и даже воду смываю". у вас или есть установка делать что-то хорошо
и надежно вне зависимости от контекста всегда и везде, или же её нет.
последнего я не могу назвать профессионалом своего дела вне
зависимости от того, что, где и как он написал.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от anonymous

> Код не становится говном из-за того, что какой-то klalafuda так считает. Пусть приведет пример как надо было написать. Там и посмотрим насколько к его мнению стоит прислушиваться.

как я уже упомянул в первом сообщении, такого примера не существует. ладно, облегчим утверждение: лично я такого примера не встречал. в любом проекте, который так или иначе попадал в поле моей деятельности всегда содержал в себе те или иные недочеты, ошибки, etc.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от alex_custov

> Мне глубоко всё равно, что ты там и где будешь выражать. Я только констатирую факт. Таких людей как ты постоянно просишь дать ссылки на OS проекты, в которых они принимают участие, а в ответ - тишина. Зато разглагольствований про говёный код других проектов - предостаточно.

если OS проекты - это все, что вы в состоянии себе представить в качестве мерила разработчика, то нам явно не о чем дискутировать.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

А теперь представим себе реальный _ну_очень_сложный_ проект
с _большим_ количеством namespace'ов:

class A
{
public:
    topnamespace::subnamespace::onemoresubnamespace::VeryGoodNamedClass foo() {
        std::stringstream s;
        s << othertopnamespace::subnamespace::onemoresubnamespace::OneMoreVeryGoodNamedClass(
) << std::endl;
        return topnamespace::subnamespace::onemoresubnamespace::VeryGoodNamedClass(s.str());
    }
}

Читабельно, правда?

Теперь представь себе несколько мегабайт кода в таком стиле.
Да, одним уровнем namespace'ов не обойтись - подсистем слишком
много и они сложные, всё равно получается что-то вроде
"namespace topnamespace_subnamespace_subsubnamespace".

Заодно обрати внимание, что в исходном коде было "using", а не
"using namespace", что при желании позволяет посмотреть, что же
именно импортируется в текущий namespace.

Это уж не говоря о том, что при желании хакер ВасяПетя может
создать макрос с именем, совпадающим с твоим namespace, и
успешно сломать всю предлагаемую тобой конструкцию.

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

execve
()
Ответ на: комментарий от execve

> А теперь представим себе реальный _ну_очень_сложный_ проект с _большим_ количеством namespace'ов:
> Читабельно, правда?

вас кто-то заставляет использовать глубоко вложенные пространства имен с названиями по 30 символов каждое? тогда ой. тут уже действительно мало что поможет и использование using namespace на фоне остальных проблем проекта - это так, детские шалости.

> Теперь представь себе несколько мегабайт кода в таком стиле.
> Да, одним уровнем namespace'ов не обойтись - подсистем слишком
много и они сложные, всё равно получается что-то вроде
"namespace topnamespace_subnamespace_subsubnamespace".

я прекрасно представляю себе проекты на десятки и сотни мегабайт исходного кода в которых сам участвовал. и, как ни странно, пока что не встречал такого, простите, маразма как указано выше. единственное, пожалуй, что приходит на ум с перевложенными пространствами имен - это boost. два уровня namespace - это максимум.

ps: можно ведь и классы объявлять один внутри другого и то-же довести идею до полного абсурда. но это уже скорее из области ССЗБ. при большом желании прострелить себе ногу можно чем угодно, даже зубной щеткой.

> Заодно обрати внимание, что в исходном коде было "using", а не
"using namespace", что при желании позволяет посмотреть, что же
именно импортируется в текущий namespace.

о да, это да. для того, чтобы что-то безопасно сделать, нужно перешерстить весь исходник - а он большой а их много.. - и тщательно проверить, нет ли где чего не того. а так-же btw всё дерево включаемых файлов бо находятся умельцы, которые и туда любят забабахать using. ну уж если счастье шоб наступило то чтобы всем и сразу.

не проще его просто НЕ использовать и на этом честно успокоиться?

> Это уж не говоря о том, что при желании хакер ВасяПетя может
создать макрос с именем, совпадающим с твоим namespace, и
успешно сломать всю предлагаемую тобой конструкцию.

макрос? в С++ проекте? зачем?
разве что врапер на защиту от повторного включения.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

>>если OS проекты - это все, что вы в состоянии себе представить в качестве мерила разработчика, то нам явно не о чем дискутировать.

конкретно сейчас мы обсуждаем OS, и ты не преминул даже Qt обкакать.

alex_custov ★★★★★
()
Ответ на: комментарий от alex_custov

> конкретно сейчас мы обсуждаем OS, и ты не преминул даже Qt обкакать.

"а меня он грязнухой-ползухой обозвал!"

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> если OS проекты - это все, что вы в состоянии себе представить в качестве мерила разработчика, то нам явно не о чем дискутировать.

Что вы имеете ввиду?

UVV ★★★★★
()
Ответ на: комментарий от klalafuda

Согласен с execve. "using namespace xxx;" может быть вреден, но в рассматриваемом коде использовался аккуратный и точный "using ns::classname".

Насчет вредности "using namespace xxx;" спорить не стану - мне кажется, что это просто предубеждение и перестраховка, но я лично не сталкивался с проектами "на сотни мегабайт исходного кода". Хотя Страуструп - как раз специалист по разработке больших программных систем ;)

tailgunner ★★★★★
()
Ответ на: комментарий от klalafuda

скажем вы используете некую либу где:

// -- либа --
namespace ExternalLibrary {
    class A {};
};


// вашь код
namespace YourCode {
  class B {
  public:
    // note - exception safe
    B& operator = ( B const& tmp ) {
      B tmp(rhs);
      swap(tmp);
      return *this;
    }
  private:
    void swap( B& b ) throw () {
       // nothrowing std::swap
       std::swap(a, b.a);
    }
  private:
    ExternalLibrary::A a;
  };
}


все отлично, но вот однажды, левые либоделатели поменяли свой класс так, что звать 'std::swap' таперича никак нельзя и оне добавили в свою либу  свой swap.

// -- либа --
namespace ExternalLibrary {
    class A {};
    void swap( A& lhs, A& rhs);
};

вашь код отлично компилится, однако работает неверно, ибо везде зовется std::swap, т.к. полная квалификация недает использовать ADL. что делать? не использовать полную квалификацию, а делать так: 

namespace YourCode {
  class B {
  public:
    // note - exception safe
    B& operator = ( B const& tmp ) {
      B tmp(rhs);
      swap(tmp);
      return *this;
    }
  private:
    void swap( B& b ) throw () {
       // nothrowing std::swap
       using std::swap;
       // если  в ExternalLibrary есть swap, 
       // то ADL найдет его, иначе будет использован
       // swap из std.
       swap(a, b.a);
    }
  private:
    ExternalLibrary::A a;
  };
}


соответственно в вашем случае

public :
    test() {
        // решает все проблемы и не запрещает ADL 
        // если он нужен
        using a::foo;
        std::cout << "foo is " << foo() << std::endl;
    }

private :
    char foo() {
        return 'c';
    }
};

aydef
()
Ответ на: комментарий от klalafuda

> думаю, идея понятна.

Спасибо за объяснение, идея понятна :-)

smh ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.