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

Перегрузка оператора ++ , деструктор и конструктор копий - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Объект string! http://www.cyberforum.ru/cpp-beginners/thread156519.html
Нужно чтобы при вводе имени файла(даже с пробелами), или вообще других данных, они заносились в объект типа string! C помощью каких функций или операторов можно это сделать? Потому что если это делать с помощью объекта cin, то заносится не полное имя файла, если в нем были пробелы!!! Заранее благодарен! Вот пример кода: #include "stdafx.h" #include <iostream> #include <fstream> #include...
C++ Вопросы насчёт быстрой сортировки Здравствуйте. Объясните, пожалуйста. Есть алгоритм быстрой сортировки: Код: int shag=1; void quickSort(int arr, int left, int right, char v) { cout <<"--------" <<shag <<"-------" <<endl; if(v=='a') {cout <<" Вариант №1" <<endl; shag++;} http://www.cyberforum.ru/cpp-beginners/thread156477.html
C++ Измерение времени компиляции
как узнать время компиляции исходного текста и размер памяти, которую програма использует
C++ Запись пользовательского класса
Всем доброе время суток! Пишу класс шаблон, застрял на одном месте и не могу понять в чем проблема ... имеется пользовательский класс, в нем определена функция перегрузки оператора вставки в файл: ofstream& operator << (ofstream& s, user_type& ut) { s << ut.fstreet << " " << ut.fhouse; return s; } В классе шаблоне имеется функция записи элементов однонаправленного кольцевого списка в...
C++ Дереференс указателей http://www.cyberforum.ru/cpp-beginners/thread156432.html
после прочтения мануала появилась необходимость использовать beth = *ted; но оно выдает еррор C2100 =\ надо: есть size_t arg = 0x12345 нужно прочитать int по адресу из arg, можно ли это сделать поинтерами * или & ? или только кастом можно?
C++ ошибка с WINDOWS.H После подключения в одном из модулей модуля "afxwin.h" при компиляции появилась ошибка fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h> В чём ошибка? И как её устранить? подробнее

Показать сообщение отдельно
FireNovel
 Аватар для FireNovel
150 / 73 / 8
Регистрация: 09.04.2010
Сообщений: 297
30.07.2010, 14:34     Перегрузка оператора ++ , деструктор и конструктор копий
Привет всем!

В продолжение Этой темы появились новые вопросы и непонятки. Буду признателен за советы и разъяснения

Начну с самого начала...

Пишу class - обертку для файла. Цель - упростить операции доступа к содержимому файла.

Приблизительный план: (может, как по другому можно)
класс должен содержать, и выдавать по требованию, такие данные;
текущее положение курсора (номер строки и номер символа в строке)
текущий символ.
Смещешие курсора сделать с помощью операторов ++ и --
На каждый файл отдельный объект.
В конструкторе инициал. поля и загружается часть файла в массив.

Дальше будет видно...

текущие наработки:
file_pos.h
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
80
81
82
83
84
85
86
87
88
89
90
91
#include "io.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <malloc.h> 
#include <fcntl.h>
 
#define BUFF_SIZE 512
 
typedef unsigned int  uint_t;      // 4 - bytes ; 0 to 4,294,967,295 
 
class File_pos
{
    char * file_name;       /* Хранит имя файла */
    char * buffer;          /* Указатель на массив  содержимого файла */
 
    uint_t file_size;       /* Количество символов в файле*/
 
    /* количество элементов в буфере м. быть от 1 до BUFF_SIZE | file_size */
    uint_t readed_elements;  /* если равно file_size то перезагрузка не нужна */
    
    uint_t cur_pos;         /* Текущее полож. курсора, / 1 до file_size */
 
    uint_t line;            /* текущая строка    / от 1 и до 4,294,967,295 */  
    uint_t cursor;          /* позиция в строке  / от 1 и до 4,294,967,295 */
 
    uint_t blocnum;         /* номер прочитанного блока */    
 
    bool need_reload;       /* нужна ли будет "до-загрузка файла" */
 
    bool eof;       /* Ни конец ли файла? */
    //bool bof;       /* Ни начало ли файла */
 
 
    //char * load_file( const char * filename, /* out */ uint_t * count_symb );
    
    char * load_buff ();
  
 
    inline void get_file_size ();
 
    int read_buff ( uint_t buff_size, bool backflag );
 
    
public :
 
    File_pos (const char * filename );
    File_pos (const File_pos &obj ); /* Конструктор копирования */
    ~File_pos ();
 
    File_pos operator++();
    //File_pos operator--();
 
    uint_t  get_Line ()     { return line; }
    uint_t  get_Cursor ()   { return cursor; }
    
    char    get_Symb ()     { return *buffer; } /*Текущий символ */
 
    bool    is_eof ()       { return  eof; }
    
 /* FIXME  Проверить правильно ли определяю начало файла */
    bool    is_begin ()     { return ( cur_pos == 0 ); }
 
 
    //int set_New_file ( const char * filename );
 
  
 
    void Print() 
    { 
        switch ( this->get_Symb() )
        {
        case '\r' :
            printf ("Текущий символ \" \\r\" на позиции Ln (%i) Cur (%i)\n", line, cursor);
            break;
        case '\n' :
            printf ("Текущий символ \" \\n\" на позиции Ln (%i) Cur (%i)\n", line, cursor);
            break;
        case '\t' :
            printf ("Текущий символ \" \\t\" на позиции Ln (%i) Cur (%i)\n", line, cursor);
            break;
        case '\0' :
            printf ("Текущий символ \" \\0\" на позиции Ln (%i) Cur (%i)\n", line, cursor);
            break;
        default :
            printf ( "Текущий символ \" %-2c\" на позиции Ln (%i) Cur (%i)\n",
                    this->get_Symb(), line, cursor ); 
            break;
        }
    }
};

file_pos.cpp
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "file_pos.h"
 
/* Конструктор */
File_pos::File_pos (const char * filename )
{
 
    this->file_name = _strdup ( filename );
 
    this->get_file_size();  /* Инициализируем длину файла */
 
    this->blocnum = 0;
 
    cur_pos = 1;
 
    read_buff( BUFF_SIZE, false ); // Загружаем первый блок в память
 
    need_reload = (file_size > readed_elements );
 
    eof = file_size == 0;
    
    line    = 1;
    cursor  = 1;       
}
/*-----------------*/
 
/* Конструктор копирования */
File_pos::File_pos(const File_pos &obj)
{
    size_t sz;
    this->blocnum   = obj.blocnum;
    this->cur_pos   = obj.cur_pos;
    this->cursor    = obj.cursor;
    this->eof       = obj.eof;
    this->file_size = obj.file_size;
    this->line      = obj.line;
    this->need_reload       = obj.need_reload;
    this->readed_elements   = obj.readed_elements;
 
    this->file_name = _strdup ( obj.file_name );
    this->buffer = new char[ sz = obj.readed_elements ];
/*FIXME Добавить оработку исключительных ситуаций */
    
    for (size_t i = 0; i < sz; ++i)
        this->buffer[i] = obj.buffer[i];
 
}
 
 
/*-----Деструктор-----*/
File_pos::~File_pos()
{
/*FIXME Переделать под delete*/
    free ( this->file_name );
    free ( this->buffer );      
    printf ("Destructor... \n" );
}
 
/*--Определяет длину файла--*/
void
File_pos::get_file_size ()
{
    int fh;
    if ( (fh = _open( this->file_name, _O_BINARY | O_RDONLY )) == -1)
    {
        perror("Open File");
        return;
    }
 
    _lseek ( fh, 0L, SEEK_SET );  // Переводим курсор вначало    
 
    /* определяем количество символов в файле */
 
    if ( (this->file_size = _lseek ( fh, 0L, SEEK_END ) ) == 0 )
    {
        puts( "File is empty..." );
        return;
    }
    _close ( fh );
}
 
/*-------------------*/
 
 
/*Читает "кусочек" данный в массив */
int
File_pos::read_buff ( uint_t buff_size, bool backflag )
{
    int fh;
    if ( (fh = _open( this->file_name, _O_BINARY | O_RDONLY )) == -1)
    {
        perror("Open File");
        return -1;
    }
 
    /*FIXME тут как раз и будет разветвление читать вперед или назад */
    /* возможно изменять память нужно с помощью realloc() */
 
    if ( backflag )
    {
        
    }
    else
    {
        size_t bufsz = ( file_size - blocnum * buff_size < buff_size ) ? 
                                    ( file_size - blocnum * buff_size ) : buff_size;  
        
        /* Выделяем память для элементов массива */
/*FIXME Переделать под new*/
        if ( ( this->buffer = (char *) malloc ( bufsz * sizeof ( char ) ) ) == NULL )
        {
            perror ( "Can't allocate memory..." );
            return -2;
        }
        
        if ( ( readed_elements = _read ( fh, buffer, buff_size ) ) == -1)
        {
            perror ( "reading problem..." );
            return NULL;
        }
        ++blocnum;  /*ТОЛЬКО в блоке NEXT */
 
    }
    _close ( fh );
 
    return 0;
}
/*----------------------------*/
 
File_pos
File_pos::operator++ ()
{
    /* если достигли последнего элемента в буфере и есть еще что перезагрузить */
    /*if ( cur_pos == readed_elements && need_reload )
    {
        reload_file();
    }
    else
    */
 
    if ( cur_pos == file_size )    
        this->eof = true;
   
 
    /* Можно ли сместить курсор */
    if ( cur_pos < file_size )
    { 
        if ( this->get_Symb() != '\n')
        {
            ++cursor;
        }
        else
        {
            ++line;
            cursor = 1;            
        }
 
        ++buffer;                
 
        ++cur_pos;           
    }
    
    return *this;
}
 
/*----------------*/

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include "file_pos.h"
#include "locale.h"
 
int main()
{ 
    setlocale( LC_ALL, "" );
 
    File_pos f1( "test.txt" );
 
    while ( !f1.is_eof() )
    {
        f1.Print();
        ++f1;
    }
 
    system ("PAUSE");
    exit ( EXIT_SUCCESS );
}


Для перемещения по файлу решил перегрузить операторы инкремента и декемента
Сделал смещение вперед (оператор ++) И столкнулся с проблемой:

функция operator++ () возвращает объект и каждый раз при возврате из нее вызывается деструктор, в котором освобождается память (а ее освобождать не нужно).

Решил проблему с помощью Конструктора копий.

И тут, главный, на данном этапе, вопрос

Правильно ли сделал конструктор копирования? в нем каждый раз делается копия массива buffer (даже 2 массива file_name и buffer).
При прогоне по всем элементам файла такое копирование происходит много раз..
По-моему - это не оптимально
Может я не так делаю?
Конструктор копирования
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Конструктор копирования */
File_pos::File_pos(const File_pos &obj)
{
    size_t sz;
    this->blocnum   = obj.blocnum;
    this->cur_pos   = obj.cur_pos;
    this->cursor    = obj.cursor;
    this->eof       = obj.eof;
    this->file_size = obj.file_size;
    this->line      = obj.line;
    this->need_reload       = obj.need_reload;
    this->readed_elements   = obj.readed_elements;
 
    this->file_name = _strdup ( obj.file_name );
    this->buffer = new char[ sz = obj.readed_elements ];
/*FIXME Добавить оработку исключительных ситуаций */
    
    for (size_t i = 0; i < sz; ++i)
        this->buffer[i] = obj.buffer[i];
 
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 10:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru