Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.82
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
#1

Класс содержащий объект типа ofstream - не компилится! - C++

28.07.2012, 14:03. Просмотров 3321. Ответов 21
Метки нет (Все метки)

Здравствуйте! Помогите пожалуйста!=)

есть код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <fstream>
 
    class Monstr
    {
        private:
            std::ofstream out;
        public:
            Monstr() : out("test", std::ios::app | std::ios::out){}
            ~Monstr();
    };
 
 
int main(void)
{
    Monstr Y;
    Monstr X(Y);
    system("pause");
    return 0;
}
есть ошибка:

1>c:\program files\microsoft visual studio 10.0\vc\include\ostream(604): error C2249: std::basic_ios<_Elem,_Traits>::operator =: нет доступного пути к private член, объявленному в виртуальном базовом классе "std::basic_ios<_Elem,_Traits>"
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\ios(177): см. объявление "std::basic_ios<_Elem,_Traits>::operator ="
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> Сообщение диагностики возникло в созданной компилятором функции "std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::operator =(const std::basic_ostream<_Elem,_Traits> &)"
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1>


Почему?

Добавлено через 5 минут
И если размещают объекты класса [i/o]fstream в классе, то как? Или что-то в конструкторе копирования для этого делают обычно? И еще, как вернуть имя файла, на который ссылается объект класса [i/o]fstream. Т.е.

ofstream out1("test");
ofstream out2(out.вернуть_имя_файла);?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2012, 14:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Класс содержащий объект типа ofstream - не компилится! (C++):

Есть объект типа T, но если вместо него подставить вызов функции, возвращающей T, код не компилится, почему? - C++
Есть объект типа vector&lt;int&gt;, но если вместо него подставить вызов функции, возвращающей vector&lt;int&gt;, код не компилится (template мутит...

Объявить класс содержащий 1 переменную А закрытого типа. - C++
объявить класс содержащий 1 переменную А закрытого типа. И функцию которая считывает переменную введенную с клавиатуры и выводит на экран....

Создайте класс Тест, содержащий две закрытые переменные типа int с именами count и max - C++

Определить класс химический элемент, содержащий информацию о названии элемента его химических свойствах. Определить класс медикаменты, содержащий разн - C++
Определить класс химический элемент, содержащий информацию о названии элемента его химических свойствах. Определить класс медикаменты,...

Создайте класс employee, который содержит имя (объект класса string) и номер (типа long) служащего - C++
Создайте класс employee, который содержит имя (объект класса string) и но- мер (типа long) служащего. Включите в него метод getdata(),...

Нюансы синтаксиса: использование объектов типа ofstream - C++
Куда нужно дописать std:: ? #include &lt;iostream&gt; #include &lt;fstream&gt; int main (void){ ofstream file; file.open...

21
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
28.07.2012, 14:07 #2
Создается конструктор копирования по умолчанию, в котором идет по элементное присваивание. А объекты типа std::ofstream нельзя присваивать через оператор =. Определите явный конструктор копии, и в нем производите действия.
0
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
28.07.2012, 15:37  [ТС] #3
А что в конструкторе копирования написать, чтобы данное поле во всех экземплярах класса ссылалось на один и тот же файл?
0
MrCold
855 / 753 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
28.07.2012, 17:43 #4
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
конструкторе копирования написать
ИМХО Лучше определить метод(ы) для работы
с файлом

Объекты кл. ofstream, ifstream создавать в main

и передавать в эти методы

Примерчик
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <fstream>
 
    class Monstr
    {
        private:
 
           int age;
 
        public:
 
            Monstr() : age ( 0 ){}
            Monstr( int age_ ) : age ( age_ ){}
            ~Monstr(){};
            void fileWork ( std::ofstream & f );
 
    };
 
     void Monstr::fileWork ( std::ofstream & f )
          {
                  f << age << std::endl;
          }
 
 
int main(void)
{
 
   Monstr obj ( 33 );
   Monstr obj2 ( 56 );
 
   std::ofstream out;
   out.open ( "C:\\test.txt"  );
 
   obj.fileWork ( out );
   obj2.fileWork ( out );
 
   out.close();
 
    system("pause");
    return 0;
}
в файле получим
Код
33
56
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
конструкторе копирования написать
Alberto_Timakov, загляните в ios_base.h и увидите что
конструктор копии и оператор присваивания для класса IOS_BASE
находятся в разделе private

потому
Цитата Сообщение от Toshkarik Посмотреть сообщение
А объекты типа std::ofstream нельзя присваивать через оператор =.
0
Avazart
Нарушитель
Эксперт С++
7226 / 5398 / 291
Регистрация: 10.12.2010
Сообщений: 23,931
Записей в блоге: 17
28.07.2012, 20:47 #5
Думаю сама идея объявления потока в классе как члена- не хорошая
0
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 02:08  [ТС] #6
Цитата Сообщение от MrCold Посмотреть сообщение
Объекты кл. ofstream, ifstream создавать в main
и передавать в эти методы
Спасибо! верно! Но что, если я хочу, к примеру, какую-нибудь отладочную печать в файл в деструкторе написать? Ему ведь параметров передавать нельзя...Ну или вообще может есть случаи, положим исключительные, когда прям надо чтобы поле было типа fstream?

Цитата Сообщение от Avazart Посмотреть сообщение
Думаю сама идея объявления потока в классе как члена- не хорошая
А почему?
0
Avazart
Нарушитель
Эксперт С++
7226 / 5398 / 291
Регистрация: 10.12.2010
Сообщений: 23,931
Записей в блоге: 17
29.07.2012, 08:36 #7
По тому что лучше локализовать существование потока внутри метода, там же обрабатывать ошибки в/в.
0
MrCold
855 / 753 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 09:57 #8
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
может есть случаи, положим исключительные, когда прям надо чтобы поле было типа fstream?
Пишем значение переменной age в файл
затем выводим

для каждого объекта Monstr свой файл
( конечно можно и в один файл
записи добавлять )

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <fstream>
 
    class Monstr
    {
        private:
 
           int age;
           char *fname;
           std::ofstream out;
           std::ifstream in;
 
    private:
 
        Monstr& operator=( const Monstr& src );
        Monstr( const Monstr& src );
 
    public:
 
         void 
               writeFile() 
           {
                out.open ( fname );
                 if ( ! out )
                 {
                     std::cerr << "Error in opening file for writing.";
                       exit ( -1 );
                 }
            
               out << age << std::endl;
               out.close();
           }
 
          void 
               readFile()
           {
                 in.open ( fname );
                 if ( ! in )
                 {
                     std::cerr << "Error in opening file for reading.";
                       exit ( -1 );
                 }
               int val = 0;
                        
                   in >> val ;
                   std::cout << val << std::endl; 
                   in.close();
           }
 
        public:
 
            Monstr( const char *fname_ = "C:\\file1.txt" , int age_ = 23 ) :
              age ( age_)
            {
                fname = new char [ strlen ( fname_) + 1 ];
                strcpy( fname, fname_);
            }
 
            ~Monstr()
            {
               delete[] fname;
            }    
 
    };
 
int main(void)
{
   Monstr obj ( "C:\\file1.txt" );
   Monstr obj2 ( "C:\\file2.txt" , 53 );
 
   obj.writeFile();
   obj.readFile();
 
   obj2.writeFile();
   obj2.readFile();
 
    system("pause");
    return 0;
}
Вывод в консоль :
Код
23
53
В файлах :

file1: 23
file2: 53
0
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 10:22  [ТС] #9
Вы написали:
Цитата Сообщение от MrCold Посмотреть сообщение
private:
Monstr& operator=( const Monstr& src );
Monstr( const Monstr& src );
Во-первых, почему именно private?
Во-вторых, где определение?)

Добавлено через 9 минут
Я не фига не понял, как оно работает? Ведь определений даже нету? И что это из себя представляет расскажите пожалуйста...
0
MrCold
855 / 753 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:24 #10
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
Во-первых, почему именно private?
Что бы запретить присваивание ;
C++
1
2
3
Monstr obj; 
Monstr obj2 = obj; < ------ запрет 
Monstr obj3 (obj); < ------ запрет
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
Во-вторых, где определение?)
Определение уже не понадобится т.к. конструктор копии
и оператор присваивания все равно
недоступны ( private )

запрещаем присваивание, копирование
объектов потому-что
C++
1
std::ofstream out = std::ofstream out;  <  --------------- НЕЛЬЗЯ!!!!!
0
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 10:40  [ТС] #11
Цитата Сообщение от MrCold Посмотреть сообщение
Что бы запретить присваивание ;
Познавательно, спасибо!

Так, енто понятно, ну, а если все таки объекты у меня в программе копируются...то что тогда...может можно как-нибудь с указателями?

Я просто пробовал писать вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <fstream>
 
    class Monstr
    {
        private:
            std::ofstream * out;
        public:
            Monstr(){out = new std::ofstream ("test", std::ios::app | std::ios::out);}
            Monstr(const Monstr &);
            ~Monstr(){*out << "destructor" << std::endl; *out.close(); }
    };
 
    Monstr::Monstr(const Monstr & monstr)
    {
        out = monstr.out;
        *out << "constructor_copy" << std::endl;
    }
 
 
int main(void)
{
    Monstr Y;
    Monstr X(Y);
    system("pause");
    return 0;
}
- Работает, но без delete out в деструкторе ~Monstr(). С delete естественно возникает ошибка из-за повторного освобождения одной и той же области...Без delete это бред, я понимаю, но может можно еще как-то????
0
MrCold
855 / 753 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:58 #12
C++
1
2
private:
            std::ofstream  out;
Зачем вообще ofstream, ifstream
выносить из методов
работайте внутри методов

открыли - записали- закрыли
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
   void    writeFile() 
        {
          std::ofstream  out;
       out.open ( "file.txt" , std::ios::app );
                if ( ! out )
                {
                     std::cerr << "Error in opening file.";
                      exit ( -1 );
                }
         
              out << age << std::endl;
               out.close();
         }
Это последнее что предложу
1
Avazart
Нарушитель
Эксперт С++
7226 / 5398 / 291
Регистрация: 10.12.2010
Сообщений: 23,931
Записей в блоге: 17
29.07.2012, 11:44 #13
C++
1
2
3
4
5
6
7
bool Monstr::writeFile(std::string filename) 
  {
    std::ofstream out(filename.c_str());
    if ( ! out ) return false;
    out << age << std::endl;
    return true;
  }
C++
1
2
Monstr Obj;
if(! Obj.writeFile("1.txt") ) std::cerr<<"Error!!!"<<std::endl;
Если использовать поток как член класса то после возникновении ошибки в потоке при i/o, класс может стать не работоспособным.
1
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 13:48  [ТС] #14
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
0
Avazart
Нарушитель
Эксперт С++
7226 / 5398 / 291
Регистрация: 10.12.2010
Сообщений: 23,931
Записей в блоге: 17
29.07.2012, 13:52 #15
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
Ну это проблемы с ошибками не решит, в отличии от локализации.
0
29.07.2012, 13:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2012, 13:52
Привет! Вот еще темы с ответами:

Нужно объект типа класс проинициализировать с помощью перегруженного конструктора Class::Class( bool a ) - C++
Плиз помогите. Не знал, что я такой чайник.) Итак: есть два класса: CMyClass.h CMyClass.cpp и

интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект - C++
Привет всем. Необходимо реализовать интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект. Не...

Не удаётся создать безымянный объект типа vector моего типа - C++
Собсно #include &lt;vector&gt; using namespace std; //Вот мой австорский тип struct kletka { int i, j; kletka(int x, int...

Класс объявление с элементом типа класс Текст - C++
Необработанное исключение в &quot;0x770015de&quot; в &quot;FAQ.exe&quot;: 0xC0000005: Нарушение прав доступа при записи...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru