Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как Вы обычно передаете stream разрабатывая парсер 
:(
    Опции темы
mes
Дата 23.6.2013, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  11:53 Найти цитируемый пост)
 Однако имеется только одно пояснение, которое я нашел зачем эти дружественные были введены в язык и оно написано в книге Страуструпа про Дизайн и Эволюцию языка.

3.6.2 ?  оно и есть  smile 


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



mes, Да, оно самое! ;) Кроме него больше не видел ни одного пояснения. Но то что приведено, на столько мало. Что невозможно сразу сформировать свое мнение о дружественных. Приходится ждать появления опыта и отказаться до момента его появления )
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  12:23 Найти цитируемый пост)
 Но то что приведено, на столько мало. Что невозможно сразу сформировать свое мнение о дружественных

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


--------------------
PM MAIL WWW   Вверх
volatile
Дата 23.6.2013, 13:55 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(EvilsInterrupt @  23.6.2013,  11:40 Найти цитируемый пост)
Чисто технически пользовательский код не может видеть приватную часть другого класса. Но это можно организовать объявив в объявлении класса эту функцию дружественной.

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



PM MAIL   Вверх
EvilsInterrupt
Дата 23.6.2013, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Цитата(volatile @  23.6.2013,  14:55 Найти цитируемый пост)
в том что  вы считаете что дружественная функция имеет отношение к пользовательскому коду.

Да, именно так и считаю. А как иначе если она видна пользовательскому коду и не спрятана в private и namespace detailed ?
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  12:58 Найти цитируемый пост)
 А как иначе если она видна пользовательскому коду

Вы путатете понятия "интерфейс (библиотеки)" и "пользовательский код"

Добавлено через 45 секунд
для пользователя все равно, дружественная ли функция, или нет...



--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Судя по всему, собравшиеся mes и volatile предпочли бы такой вариант:

Код

namespace SuperFormat
{


struct FirstHeader_t
{
    uint8_t   Magic;
    uint32_t  SecondHeaderOffset;
};

struct SecondHeader_t
{
    uint16_t Magic;
};


class SFImage
{
public:
    typedef  std::list<SecondHeader_t>  SecondHeaders_t;

public:
    friend  void read( std::istream& stream, SFImage* image );
    friend  void write( std::ostream& stream, SFImage& image );

public:
    FirstHeader_t   FirstHeader;
    SecondHeaders_t SecondHeaders;

private:

    void readFirstHeader( std::istream& stream )
    {
        char * ptr = reinterpret_cast<char*>(&FirstHeader);
        std::streamsize sz = sizeof(FirstHeader);
        stream.read( ptr, sz );
    }

    void readSecondHeader( std::istream& stream )
    {
        stream.seekg(FirstHeader.SecondHeaderOffset);
        SecondHeader_t header;
        header.Magic = 0xFF;
        while (header.Magic != 0)
        {
            char * ptr = reinterpret_cast<char *>(&header);
            std::streamsize sz = sizeof(SecondHeader_t);
            stream.read( ptr, sz );
            SecondHeaders.push_back(header);
        }
    }

    void writeFirstHeader( std::ostream& stream )
    {
        const char * ptr = reinterpret_cast<const char*>(&FirstHeader);
        std::streamsize sz = static_cast<std::streamsize>( sizeof(FirstHeader) );
        stream.write( ptr, sz );
    }

    void writeSecondHeader( std::ostream& stream )
    {
        typedef  SecondHeaders_t::const_iterator  HeaderIter_type;
        HeaderIter_type it = SecondHeaders.begin();
        while ( it != SecondHeaders.end() )
        {
            char * ptr = reinterpret_cast<char *>( &it );
            std::streamsize sz = sizeof(SecondHeader_t);
            stream.write( ptr, sz );
        }
    }
};



void read( std::istream& stream, SFImage* image )
{
    std::streampos pos = stream.tellg();
    image->readFirstHeader(stream);
    image->readSecondHeader(stream);
    stream.seekg(pos);
}

void write( std::ostream& stream, SFImage& image )
{
    std::streampos pos = stream.tellp();
    image.writeFirstHeader(stream);
    image.writeSecondHeader(stream);
    stream.seekp(pos);
}



template<typename char_type, typename char_traits>
inline
std::basic_istream<char_type, char_traits>&
operator >> ( std::basic_istream<char_type, char_traits>& stream, SFImage& image )
{
    read( stream, &image );
    return stream;
}

template<typename char_type, typename char_traits>
inline
std::basic_ostream<char_type, char_traits>& 
operator << ( std::basic_ostream<char_type, char_traits>& stream, SFImage& image )
{
    write( stream, image );
    return stream;
}


} // namespace SuperFormat


Верно?
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  13:21 Найти цитируемый пост)
собравшиеся mes и volatile предпочли бы такой вариант: 

от лица mes : не совсем или даже совсем не.. 



--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Цитата(mes @  23.6.2013,  16:11 Найти цитируемый пост)
от лица mes : не совсем или даже совсем не.. 

Ок, а какой тогда код был бы? Задача маленькая, думаю займет у вас не более 5 мин. ;)
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



для приведенного куска, аддптировано под write/read smile

Код

namespace SuperFormat
{
struct FirstHeader_t
{
    uint8_t   Magic;
    uint32_t  SecondHeaderOffset;
};
struct SecondHeader_t
{
    uint16_t Magic;
};

typedef  std::list<SecondHeader_t>  SecondHeaders_t;

struct SFImage
{
    FirstHeader_t   FirstHeader;
    SecondHeaders_t SecondHeaders;
};

void write(.., FirstHeader_t const&) {..}
void write(.., SecondHeader_t const&) {..}
void write(.., SFImage const& img)
{
    write(.., img->FirstHeader);
     for (...) write(.., img->SecondHeaders[..]);
}
//также для read

} // namespace SuperFormat


Это сообщение отредактировал(а) mes - 23.6.2013, 17:31


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



mes, 
Если не секрет, то почему так? 

Я видел подобный способ на http://stackoverflow.com/ , но меня он отталкиваем тем что похож на процедурный подход.
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  16:41 Найти цитируемый пост)
 похож на процедурный подход

а вы наверное считаете, что запихнув все в классы получите ооп-подход smile 
замените read/write на операторы и будет вам счастие smile
 
А по сути в вашем примере чрезмерная инкапсуляция, которая прячет важные сущности, не принося никакой пользы этим, зато сложностей и зависимостей добавляет кучу smile

Добавлено через 10 минут и 8 секунд
Цитата(EvilsInterrupt @  23.6.2013,  16:41 Найти цитируемый пост)
 на процедурный подход.

и да : крылья...ноги...главное хвост! ©


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



mes, 
Приведу твой код, тут:
Код

namespace SuperFormat
{


struct FirstHeader_t
{
    uint8_t   Magic;
    uint32_t  SecondHeaderOffset;
};

struct SecondHeader_t
{
    uint16_t Magic;
};

typedef  std::list<SecondHeader_t>  SecondHeaders_t;


struct SFImage
{
    FirstHeader_t   FirstHeader;
    SecondHeaders_t SecondHeaders;
};


template<typename Header_type>
void read( std::istream& stream, Header_type * header )
{
    char * ptr = reinterpret_cast<char*>(header);
    std::streamsize sz = sizeof(*header);
    stream.read( ptr, sz );
}

template<typename Header_type>
void write( std::ostream& stream, const Header_type& header )
{
    const char * ptr = reinterpret_cast<const char *>( &header );
    std::streamsize sz = sizeof(header);
    stream.write( ptr, sz );
}


void read( std::istream& stream, SFImage* image )
{
    std::streampos pos = stream.tellg();

    stream.seekg(0);
    read(stream, &image->FirstHeader );

    stream.seekg(image->FirstHeader.SecondHeaderOffset);

    SecondHeader_t header;
    header.Magic = 0xFF;
    while (header.Magic != 0)
    {
        read(stream, &header );
        image->SecondHeaders.push_back(header);
    }

    stream.seekg(pos);
}

void write( std::ostream& stream, SFImage& image )
{
    std::streampos pos = stream.tellp();

    stream.seekp(0);
    write(stream, image.FirstHeader );
    stream.seekp(image.FirstHeader.SecondHeaderOffset );

    typedef  SecondHeaders_t::const_iterator  HeaderIter_type;
    HeaderIter_type it = image.SecondHeaders.begin();
    HeaderIter_type end = image.SecondHeaders.end();
    while ( it != end )
    {
        write( stream, *it );
        ++it;
    }

    stream.seekp(pos);
}



template<typename char_type, typename char_traits>
inline
    std::basic_istream<char_type, char_traits>&
    operator >> ( std::basic_istream<char_type, char_traits>& stream, SFImage& image )
{
    read( stream, &image );
    return stream;
}

template<typename char_type, typename char_traits>
inline
    std::basic_ostream<char_type, char_traits>& 
    operator << ( std::basic_ostream<char_type, char_traits>& stream, SFImage& image )
{
    write( stream, image );
    return stream;
}


} // namespace SuperFormat


все верно? ;)
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 23.6.2013, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  23.6.2013,  17:19 Найти цитируемый пост)
все верно? ;) 

наполовину... 

Цитата(EvilsInterrupt @  23.6.2013,  17:19 Найти цитируемый пост)
  write(stream, image.FirstHeader );
    stream.seekp(image.FirstHeader.SecondHeaderOffset );

это использование не по назначению потока (mistreatment).. Такое можно проделывать со своим потоком, в котором Вы уверены.. Но оставлять такое поведение пользователю недопустимо.. Это место требует обязательной разгрузки через сущность..

Добавлено @ 18:56
т.е. сами header`ы у Вас вполне потоко-подходящие, а вот image нет.. Проблема в image в том, что с одной стороны вы пытаетесь сохранить структуру файла, а с другой предоставить ее как набор данных удобных пользователю.. Это две разные задачи и поэтому нежелательна реализация одной сущностью..


Это сообщение отредактировал(а) mes - 23.6.2013, 18:58


--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 23.6.2013, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Цитата(mes @  23.6.2013,  19:51 Найти цитируемый пост)
 Такое можно проделывать со своим потоком, в котором Вы уверены..

Так у меня есть для этого операции первоначальных позиций для потоковых get/put указателей. Или Вы не об этом?

Добавлено через 9 минут и 22 секунды
Цитата(mes @  23.6.2013,  19:51 Найти цитируемый пост)
Это место требует обязательной разгрузки через сущность..

Наверное Вы про аналог sentry ?


Это сообщение отредактировал(а) EvilsInterrupt - 23.6.2013, 19:17
PM MAIL WWW ICQ Jabber   Вверх
Страницы: (4) Все 1 [2] 3 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.