Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > класс


Автор: Noname2512 21.7.2011, 20:01
привет, кто знает как класс в файл записать ? И как это сделать методом класса ?

Автор: Сыроежка 21.7.2011, 20:06
Цитата(Noname2512 @  21.7.2011,  20:01 Найти цитируемый пост)
привет, кто знает как класс в файл записать ? И как это сделать методом класса ?


Может быть вы имели в виду, как записать объект класса в файл? Если вы это имели в виду, то вам просто нужно перегрузить оператор <<, но только он не может быть методом класса, либо написать функцию - член класса, которая делает то же самое, что и перегруженный оператор <<.

Автор: Noname2512 21.7.2011, 20:13
Сыроежка, да я это имел в виду

Автор: Сыроежка 21.7.2011, 20:14
Цитата(Noname2512 @  21.7.2011,  20:13 Найти цитируемый пост)
Сыроежка, да я это имел в виду


Я вам выше ответил, скорректировав свой1 исходный ответ.

Добавлено через 4 минуты и 7 секунд
То есть есть два варианта. Первое - это написать самостоятельную функцию - перегрузку оператора <<, Ее объявление выглядит следующим образом

std::ostream & operator <<( std::ostream &os, const MyClass &object );

Второе - написать функцию член класса, например

std::ostream & out( std::osteram &os ) const;
 

Автор: Noname2512 21.7.2011, 20:19
а как это делается то ?

Автор: Сыроежка 21.7.2011, 20:24
Нужно определение вашего класса, и что вы хотите поместить из класса в выходной поток.

Например,

Код

class Int
{
public:
   Int( int i = 0 ) : x( i ) {}
   std::ostream & out( std::ostream &os ) const
   {
      os << x;
      return ( os );
   }
private:
   int x;
};

int main()
{
   Int a( 10 );

   a.out( std::cout );
}


Либо написать для этого класса перегруженный оператор <<

Код

std::ostream & operator <<( std::ostream &os, const Int &rhs )
{
   return ( rhs.out( os ) );
}


Я это написал "на коленках", так что могут быть опечатки.

Автор: Noname2512 22.7.2011, 10:44
было бы у меня 100 постов )

Автор: borisbn 22.7.2011, 11:06
Noname2512, +-сануть Сыроежке ?

Автор: triclosan 22.7.2011, 15:40
borisbn, догадываюсь к какой кнопке у тебя рука тянется.

Автор: vedun 22.7.2011, 15:49
Цитата(Сыроежка @ 21.7.2011,  20:24)
Нужно определение вашего класса, и что вы хотите поместить из класса в выходной поток.

Например,

Код

class Int
{
public:
   Int( int i = 0 ) : x( i ) {}
   std::ostream & out( std::ostream &os ) const
   {
      os << x;
      return ( os );
   }
private:
   int x;
};

int main()
{
   Int a( 10 );

   a.out( std::cout );
}


Сыроежка а для чего в этом коде функция out возвращает ссылку на ostream ?

Автор: JЕT 22.7.2011, 16:12
Для каскадирования, например:
Код

a.out(std::cout).put('a');

Автор: borisbn 22.7.2011, 16:23
triclosan, smile
но в данном случае то чо ? помог человеку. ТС доволен... вон даже не появляется

Автор: voral 22.7.2011, 16:32
Цитата(JЕT @  22.7.2011,  16:12 Найти цитируемый пост)
Для каскадирования, например:

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

Автор: borisbn 22.7.2011, 16:44
voral, в своих классах есть ещё смысл возвращать ссылку на себя
Код

class MyClass
{
public:
    MyClass() : m_accum( 0 ) {}
    MyClass & operator << ( int x ) {
        m_accum += x;
        return *this;
    }
private:
int m_accum;
};

MyClass x;
x << 40 << 2;

Автор: Noname2512 22.7.2011, 18:25
Цитата(borisbn @ 22.7.2011,  11:06)
Noname2512, +-сануть Сыроежке ?

нет у меня 100 постов чтоб + - длать

Автор: borisbn 22.7.2011, 18:34
Noname2512, я за тебя могу поднять или опустить репутацию. По твоей просьбе. Плюсовать ?

Автор: Сыроежка 22.7.2011, 19:41
Цитата(vedun @  22.7.2011,  15:49 Найти цитируемый пост)
Сыроежка а для чего в этом коде функция out возвращает ссылку на ostream ? 


Цитата(JЕT @  22.7.2011,  16:12 Найти цитируемый пост)
Для каскадирования, например:

код C++
1:

a.out(std::cout).put('a');


Помимо каскадирования, как правильно указал JЕT, этот прием с использованием функции-члена класса можно использовать для построение виртуального оператора вывода. Например,

Код

struct A
{
   virtual  std::ostream & out( std::ostream &os ) const;
};

struct B : public A
{
    std::ostream & out( std::ostream &os ) const;
}'

std::ostream & operator <<( std::ostream &os, const A &rhs )
{
   return ( rhs.out( os ) );
}
   

Автор: mes 22.7.2011, 20:18
Цитата(Сыроежка @  22.7.2011,  18:41 Найти цитируемый пост)
 для построение виртуального оператора вывода. Например,

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

struct A
{
   virtual  void out( std::ostream &os ) const;
};
struct B : public A
{
    /*override*/ void out( std::ostream &os ) const;
}'
std::ostream & operator <<( std::ostream &os, const A &rhs )
{
   rhs.out( os );
   return os;
}



Автор: borisbn 22.7.2011, 20:25
mes, чего-то особо не вижу разницы, кроме того, что не получится сделать то, что предложил JЕT - каскадирование

Добавлено через 4 минуты и 13 секунд
Цитата(mes @  22.7.2011,  20:18 Найти цитируемый пост)
/*override*/

надеюсь это LGPL ? можно взять на вооружение ? smile

Автор: Сыроежка 22.7.2011, 21:15
Цитата(mes @  22.7.2011,  20:18 Найти цитируемый пост)
обычно стараются разгрузить виртуальный метод, чтоб он делал минимум действий, для обеспечения большей надежностти и удобства при переопределении.. 
поэтому код из предыдущего поста я бы написал так :

код C++

struct A
{
   virtual  void out( std::ostream &os ) const;
};
struct B : public A
{
    /*override*/ void out( std::ostream &os ) const;
}'
std::ostream & operator <<( std::ostream &os, const A &rhs )
{
   rhs.out( os );
   return os;
}


Я не вижу какой-либо существенной "разгрузки" виртуальной функции, но я вижу существенные недостатки в интерфейсе. Возвращать void - это крайней случай, когда действительнот ничего полезного возвратить нельзя, и нужно стараться избегать его.

Автор: mes 22.7.2011, 22:42
Цитата(borisbn @  22.7.2011,  19:25 Найти цитируемый пост)
что не получится сделать то, что предложил JЕT - каскадирование

получится с помощью оператора <<,  к тому же это неявно пощряет использование вывода через этот оператор, а не вызовом функции.. 
еще одним подобным пощрением будет помещение функции в защищенную область.. 

Цитата(Сыроежка @  22.7.2011,  20:15 Найти цитируемый пост)
Я не вижу какой-либо существенной "разгрузки" виртуальной функции, но я вижу существенные недостатки в интерфейсе.

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

Цитата(Сыроежка @  22.7.2011,  20:15 Найти цитируемый пост)
Возвращать void - это крайней случай

это наверно в стандарте написано smile

Добавлено через 1 минуту и 25 секунд
Цитата(borisbn @  22.7.2011,  19:25 Найти цитируемый пост)
надеюсь это LGPL ? можно взять на вооружение ?

нет, это не LGPL, а абсолютно free  smile 

Автор: volatile 23.7.2011, 01:50
Цитата(Noname2512 @  21.7.2011,  20:01 Найти цитируемый пост)
привет, кто знает как класс в файл записать 

Есть такая вещь как сериализация.
От приведенных здесь примеров с выводом в потоки, выгодно отличается тем, что нужно писать только один код.
И он будет работать как на вывод, так и на ввод. Тем самым автоматически будет поддерживаться соответствие ввода-вывода.

Сериализация есть во многих библиотеках.

Автор: Сыроежка 23.7.2011, 04:00
Цитата(mes @  22.7.2011,  22:42 Найти цитируемый пост)
функция в нашем случае выполняет свою роль в паттерне виртуальный метод и предусмотрена только для возможности изменения поведения, но не для использования в качестве интерфейса..


Цитата(Сыроежка @  22.7.2011,  20:15 )
Возвращать void - это крайней случай


это наверно в стандарте написано 


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

Что касается вашей иронии насчет стандарта,  то она совершенно неуместна, и говорит лишь о том, что у вас нет никаких таргументов. Представьте себе стандартную функцию strcat, которая вместо указателя на строку, возвращала бы void.. Это было бы лишь сужение возможностей пользователя. Имп void никакой информации не несет. Поэтому умышленно ограничивать пользователя функции в инофрмации - это по крайней мере плохой стиль программирования, так как вы ограничиваете возможности пользователя, который все равно вынужден будет искать обходные пути.

То есть если вы что-то утверждаете, то следовало бы это обсоновывать, а не писать пустые высокопарные фразы.

Я вам приведу простой пример.

Код

#include   <stdio.h>

int main()
{
   int ( *fn ) ( const char * );
   const char *s = "Example";

   puts( s );

   fn = puts;
   fn( s );
}

  
Ну и в чем вы усмотрели разницу между двумя этими вызовами функции? Почему если используется указатель, то вызываемая функция puts должна быть "разгружена" по сравнению с ее же вызовом, но не через укакзатель?!

На мой взгляд вы что-то там заявили, но никакой ответсвенности за свое заявленпие не несете!

Автор: mes 23.7.2011, 21:00
Цитата(Сыроежка @  23.7.2011,  03:00 Найти цитируемый пост)
. Ваше заявление про "разгрузку виртуальных функций" никакого смысла не имеет. Виртуальные функции - это такие же функции, как и другие функции, только связывание их происходит не статически, а динамически.

Вот именно не видете, потому что вырываете слова из контекста.. Речь идет не о разгрузке виртуальных функций, а разгрузке функций паттерна виртуальный метод.. 

Цитата(Сыроежка @  23.7.2011,  03:00 Найти цитируемый пост)
Что касается вашей иронии насчет стандарта,  то она совершенно неуместна, и говорит лишь о том, что у вас нет никаких таргументов

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


Цитата(Сыроежка @  23.7.2011,  03:00 Найти цитируемый пост)
Ну и в чем вы усмотрели разницу между двумя этими вызовами функции? Почему если используется указатель, то вызываемая функция puts должна быть "разгружена" по сравнению с ее же вызовом, но не через укакзатель?!

Перечитайте еще раз, что я писал, а то пока Вы вешаете ярлыки мне в том, о чем я не говорил  smile

Добавлено через 4 минуты и 19 секунд
Цитата(Сыроежка @  23.7.2011,  03:00 Найти цитируемый пост)
Имп void никакой информации не несет. Поэтому умышленно ограничивать пользователя функции в инофрмации - это по крайней мере плохой стиль программирования, 

разгрузка - это не возвращение void, a избавление от лишних деталей, реализация которых не имеет прямого отношения к фунционалу.. 

Автор: Сыроежка 24.7.2011, 02:51
Цитата(mes @  23.7.2011,  21:00 Найти цитируемый пост)
разгрузка - это не возвращение void, a избавление от лишних деталей, реализация которых не имеет прямого отношения к фунционалу.. 


Это кто вам сказал, что это не имеет отношение к функционалу?! Функция-член класса out является открытой функцией, то есть интерфейсом. 
А знаете, откуда у вас такая ошибочная самоуверенность в "прямом отношении к функционалу"? Да потому что вы многое еще не понимпете и потому не видете, что функцию out в отличии от оператора << очень удобно ичпользовать в качяестве функции обратного вызова для различных алгоритмов. Но так как ваши знания С++ очень ограничены, и заключаются лищь в том, что вы без осмысливания цитируете различные прочитанные книжки, то такая мысль об использовании функции out  в качестве функции обратного вызова для алгоритмов естественно вам в голову не пришла. Если еще не понимаете, о чем идет речь, то попробуйте оператор << задать в качестве функции обратного вызова, и вы поймете, с какими сложностями вы столкнетесь!

Автор: mes 24.7.2011, 10:24
Цитата(Сыроежка @  24.7.2011,  01:51 Найти цитируемый пост)
Но так как ваши знания С++ очень ограничены, и заключаются лищь в том, что вы без осмысливания цитируете различные прочитанные книжки, 

прошу пример в студию (любого  осмысленного или неосмысленного) цитирования книжки за все время пребывания на этом форуме smile
все высказанное мной здесь это мой личный опыт smile
а то, что знания С++, да и программирования в целом у меня огранничены, я не спорю, куда мне до Ваших неогранниченых знаний  smile 


Цитата(Сыроежка @  24.7.2011,  01:51 Найти цитируемый пост)
Это кто вам сказал, что это не имеет отношение к функционалу?! 

судя по вашему посту, Вы опять за меня считаете, что я думаю, что функция out не имеет отношения к функционалу smile
позвольте Вас поправить.. возвращение переданного потока не является прямым функционалом виртуальной функции out..
и это никак не связано с наличием/отсутствием функции для передачи в колбяк..

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

struct A 
{
    std::ostream& out (..){ do_out(..); return os; }
  protected:
    virtual void do_out(..) { .. }
};


Цитата(Сыроежка @  24.7.2011,  01:51 Найти цитируемый пост)
Да потому что вы многое еще не понимпете и потому не видете, что функцию out в отличии от оператора << очень удобно ичпользовать в качяестве функции обратного вызова для различных алгоритмов

нда..отсутствие возвращаемоего параметра мешает Вам передать Вашу функцию как колбяк ?  smile 

Цитата(Сыроежка @  24.7.2011,  01:51 Найти цитируемый пост)
то попробуйте оператор << задать в качестве функции обратного вызова

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

Автор: xvr 24.7.2011, 10:35
Цитата(Noname2512 @  22.7.2011,  18:25 Найти цитируемый пост)
нет у меня 100 постов чтоб + - длать 

Репутацию поднял. 
И вообще Сыроежка говорит дельные вещи, пока не ошибется и вместо того, что бы признать ошибку, начинает лезть в бутылку  smile 

Автор: volatile 24.7.2011, 15:26
Цитата(Сыроежка @  24.7.2011,  02:51 Найти цитируемый пост)
потому что вы многое еще не понимпете 

Цитата(Сыроежка @  24.7.2011,  02:51 Найти цитируемый пост)
Но так как ваши знания С++ очень ограничены

Цитата(Сыроежка @  24.7.2011,  02:51 Найти цитируемый пост)
без осмысливания цитируете различные прочитанные книжки

Цитата(Сыроежка @  24.7.2011,  02:51 Найти цитируемый пост)
Если еще не понимаете, о чем идет речь, 

xvr, дело не в знаниях. С таким человеком очень трудно разговаривать.
mes, +1 за выдержку и хладнокровие.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)