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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.82
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
28.07.2012, 14:03     Класс содержащий объект типа ofstream - не компилится! #1
Здравствуйте! Помогите пожалуйста!=)

есть код:

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.вернуть_имя_файла);?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2012, 14:03     Класс содержащий объект типа ofstream - не компилится!
Посмотрите здесь:

C++ не удаётся создать безымянный объект типа vector моего типа
Объявить класс содержащий 1 переменную А закрытого типа. C++
интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект C++
C++ Нужно объект типа класс проинициализировать с помощью перегруженного конструктора Class::Class( bool a )
C++ Есть объект типа T, но если вместо него подставить вызов функции, возвращающей T, код не компилится, почему?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
28.07.2012, 14:07     Класс содержащий объект типа ofstream - не компилится! #2
Создается конструктор копирования по умолчанию, в котором идет по элементное присваивание. А объекты типа std::ofstream нельзя присваивать через оператор =. Определите явный конструктор копии, и в нем производите действия.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
28.07.2012, 15:37  [ТС]     Класс содержащий объект типа ofstream - не компилится! #3
А что в конструкторе копирования написать, чтобы данное поле во всех экземплярах класса ссылалось на один и тот же файл?
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
28.07.2012, 17:43     Класс содержащий объект типа ofstream - не компилится! #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 нельзя присваивать через оператор =.
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,561
Записей в блоге: 17
28.07.2012, 20:47     Класс содержащий объект типа ofstream - не компилится! #5
Думаю сама идея объявления потока в классе как члена- не хорошая
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 02:08  [ТС]     Класс содержащий объект типа ofstream - не компилится! #6
Цитата Сообщение от MrCold Посмотреть сообщение
Объекты кл. ofstream, ifstream создавать в main
и передавать в эти методы
Спасибо! верно! Но что, если я хочу, к примеру, какую-нибудь отладочную печать в файл в деструкторе написать? Ему ведь параметров передавать нельзя...Ну или вообще может есть случаи, положим исключительные, когда прям надо чтобы поле было типа fstream?

Цитата Сообщение от Avazart Посмотреть сообщение
Думаю сама идея объявления потока в классе как члена- не хорошая
А почему?
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,561
Записей в блоге: 17
29.07.2012, 08:36     Класс содержащий объект типа ofstream - не компилится! #7
По тому что лучше локализовать существование потока внутри метода, там же обрабатывать ошибки в/в.
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 09:57     Класс содержащий объект типа ofstream - не компилится! #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
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 10:22  [ТС]     Класс содержащий объект типа ofstream - не компилится! #9
Вы написали:
Цитата Сообщение от MrCold Посмотреть сообщение
private:
Monstr& operator=( const Monstr& src );
Monstr( const Monstr& src );
Во-первых, почему именно private?
Во-вторых, где определение?)

Добавлено через 9 минут
Я не фига не понял, как оно работает? Ведь определений даже нету? И что это из себя представляет расскажите пожалуйста...
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:24     Класс содержащий объект типа ofstream - не компилится! #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;  <  --------------- НЕЛЬЗЯ!!!!!
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 10:40  [ТС]     Класс содержащий объект типа ofstream - не компилится! #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 это бред, я понимаю, но может можно еще как-то????
MrCold
851 / 749 / 71
Регистрация: 11.01.2012
Сообщений: 1,942
29.07.2012, 10:58     Класс содержащий объект типа ofstream - не компилится! #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();
         }
Это последнее что предложу
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,561
Записей в блоге: 17
29.07.2012, 11:44     Класс содержащий объект типа ofstream - не компилится! #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, класс может стать не работоспособным.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 13:48  [ТС]     Класс содержащий объект типа ofstream - не компилится! #14
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,561
Записей в блоге: 17
29.07.2012, 13:52     Класс содержащий объект типа ofstream - не компилится! #15
Можно еще кстати его как статическое поле объявить: static std::ofstream out;=)
Ну это проблемы с ошибками не решит, в отличии от локализации.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 13:53  [ТС]     Класс содержащий объект типа ofstream - не компилится! #16
хорошо, спасибо)
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
29.07.2012, 14:06     Класс содержащий объект типа ofstream - не компилится! #17
Итак, для использования fstream как члена класса требуются веские основания. Но если такие основания есть и требуется обеспечить копирование объектов класса, содержащего какой-либо разделяемый ресурс (не только fstream), то можно воспользоваться "умными" указателями с подсчётом ссылок, например std::shared_ptr (для C++11) или boost::shared_ptr.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
29.07.2012, 23:24  [ТС]     Класс содержащий объект типа ofstream - не компилится! #18
ведь для использования 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> ? И почему файл не находится?
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,561
Записей в блоге: 17
29.07.2012, 23:25     Класс содержащий объект типа ofstream - не компилится! #19
Сначало надо установить boost
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.07.2012, 02:06     Класс содержащий объект типа ofstream - не компилится!
Еще ссылки по теме:

C++ Определить класс химический элемент, содержащий информацию о названии элемента его химических свойствах. Определить класс медикаменты, содержащий разн
C++ Создайте класс employee, который содержит имя (объект класса string) и номер (типа long) служащего
C++ Создайте класс Тест, содержащий две закрытые переменные типа int с именами count и max

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

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
30.07.2012, 02:06     Класс содержащий объект типа ofstream - не компилится! #20
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
В чем различие между shared_ptr из <boost/shared_ptr.hpp> и из <memory> ? И почему файл не находится?
В том, что сначала он появился в boost и только потом был включён в библиотеку языка. Так что если устраивает невозможность компиляции старыми компиляторами, то можно обойтись и без boost.
Если нужен буст и он уже установлен, то надо указать компилятору директорию с заголовочными файлами (ту, в которой расположена директория boost с заголовками). Где-то в настройках проекта, наверное, я не знаток VS2010.
В коде, на первый взгляд, всё нормально. В принципе деструктор и конструктор копии при этом необязательны, но и хуже от них не станет.
Yandex
Объявления
30.07.2012, 02:06     Класс содержащий объект типа ofstream - не компилится!
Ответ Создать тему
Опции темы

Текущее время: 13:04. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru