Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/55: Рейтинг темы: голосов - 55, средняя оценка - 4.82
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183

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

28.07.2012, 14:03. Показов 10525. Ответов 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>::oper ator ="
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> Сообщение диагностики возникло в созданной компилятором функции "std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Traits>::oper ator =(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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.07.2012, 14:03
Ответы с готовыми решениями:

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

Класс, содержащий объект своего класса
Если класс содержит объект своего класса. Почему при создании объекта такого класса не создается бесконечное число объектов? Ведь каждый...

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

21
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
28.07.2012, 14:07
Создается конструктор копирования по умолчанию, в котором идет по элементное присваивание. А объекты типа std::ofstream нельзя присваивать через оператор =. Определите явный конструктор копии, и в нем производите действия.
0
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
28.07.2012, 15:37  [ТС]
А что в конструкторе копирования написать, чтобы данное поле во всех экземплярах класса ссылалось на один и тот же файл?
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
28.07.2012, 17:43
Цитата Сообщение от 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;
}
в файле получим
Code
1
2
33
56
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
конструкторе копирования написать
Alberto_Timakov, загляните в ios_base.h и увидите что
конструктор копии и оператор присваивания для класса IOS_BASE
находятся в разделе private

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

Цитата Сообщение от Avazart Посмотреть сообщение
Думаю сама идея объявления потока в классе как члена- не хорошая
А почему?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.07.2012, 08:36
По тому что лучше локализовать существование потока внутри метода, там же обрабатывать ошибки в/в.
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 09:57
Цитата Сообщение от 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;
}
Вывод в консоль :
Code
1
2
23
53
В файлах :

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

Добавлено через 9 минут
Я не фига не понял, как оно работает? Ведь определений даже нету? И что это из себя представляет расскажите пожалуйста...
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:24
Цитата Сообщение от 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
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 10:40  [ТС]
Цитата Сообщение от 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
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:58
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
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.07.2012, 11:44
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
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 13:48  [ТС]
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.07.2012, 13:52
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
Ну это проблемы с ошибками не решит, в отличии от локализации.
0
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 13:53  [ТС]
хорошо, спасибо)
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
29.07.2012, 14:06
Итак, для использования fstream как члена класса требуются веские основания. Но если такие основания есть и требуется обеспечить копирование объектов класса, содержащего какой-либо разделяемый ресурс (не только fstream), то можно воспользоваться "умными" указателями с подсчётом ссылок, например std::shared_ptr (для C++11) или boost::shared_ptr.
0
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 23:24  [ТС]
ведь для использования shared_ptr надро подключить
C++
1
#include <boost/shared_ptr.hpp>
? Просто у меня он не находит такого файла (MVS2010)...

Добавлено через 23 минуты
Я правильно все сделал?

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
// tesssst.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
//#include <boost/shared_ptr.hpp>
#include <fstream>
#include <memory>
 
    class Monstr
    {
        private:
 
            static int count;
            std::string file_name;
            std::shared_ptr<std::ofstream>out;
        public:
            Monstr(std::string file_name = "test") : out(new std::ofstream(file_name, std::ios::app | std::ios::out))
            {
                this->file_name = file_name;
            //  std::ofstream out(file_name, std::ios::app | std::ios::out);
                *out << "constructor" << std::endl;
                //(*out).close();
            }
            Monstr(const Monstr &);
            ~Monstr()
            {
                //std::ofstream out("test", std::ios::app | std::ios::out);
                *out << "destructor" << std::endl;
                (*out).close();
            }
            void OUT()const{ 
                //std::ofstream out("test", std::ios::app | std::ios::out); 
                count++; 
                (*out) << "count = " << count << std::endl;
            //  out.close();
            }   
    };
 
    int Monstr::count;
 
    Monstr::Monstr(const Monstr & monstr)
    {
        this->file_name = monstr.file_name;
        //std::ofstream out("test", std::ios::app | std::ios::out);
        out = monstr.out;
        (*out) << "constructor_copy" << std::endl;
    //  (*out).close();
    }
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    Monstr Y;
    Monstr X(Y);
    X.OUT();
    Y.OUT();
    system("pause");
    return 0;
}
Добавлено через 2 минуты
В чем различие между shared_ptr из <boost/shared_ptr.hpp> и из <memory> ? И почему файл не находится?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.07.2012, 23:25
Сначало надо установить boost
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
30.07.2012, 02:06
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
В чем различие между shared_ptr из <boost/shared_ptr.hpp> и из <memory> ? И почему файл не находится?
В том, что сначала он появился в boost и только потом был включён в библиотеку языка. Так что если устраивает невозможность компиляции старыми компиляторами, то можно обойтись и без boost.
Если нужен буст и он уже установлен, то надо указать компилятору директорию с заголовочными файлами (ту, в которой расположена директория boost с заголовками). Где-то в настройках проекта, наверное, я не знаток VS2010.
В коде, на первый взгляд, всё нормально. В принципе деструктор и конструктор копии при этом необязательны, но и хуже от них не станет.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.07.2012, 02:06
Помогаю со студенческими работами здесь

Сериализовать класс, содержащий экземпляры других классов и листы с объектами типа object
Не получается сериализовать класс, содержащих экземпляры других классов и листы с объектами типа object, в которые записаны различные...

Создать класс вектор, содержащий элементы типа long double, размерность вектора
срочно!!!!!!!!!!! Пожалуйстаааа Задание 3. Создать класс вектор, содержащий элементы типа long double, размерность вектора . Определить...

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru