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

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

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

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

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

Пишу 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];
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.07.2010, 14:34     Перегрузка оператора ++ , деструктор и конструктор копий
Посмотрите здесь:

C++ Конструктор копий по умолчанию.
C++ [C++] классы конструктор копий
Конструктор копий. Оператор присваивания C++
C++ Что такое конструктор копий?
C++ Конструктор копий
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
05.08.2010, 14:54     Перегрузка оператора ++ , деструктор и конструктор копий #21
Цитата Сообщение от FireNovel Посмотреть сообщение
Как определить, что класс готов? Ведь, при разработке его, очень часто, в голову лезут разные идеи. И вроде бы и так сделать можно, и эдак - было бы хорошо организовать...
И потихоньку увязаешь в коде
Чтобы не увязать в коде, нужно хорошенько подумать, какие из этих идей ты будешь реально использовать, а без каких можно обойтись.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.08.2010, 12:19     Перегрузка оператора ++ , деструктор и конструктор копий
Еще ссылки по теме:

Конструктор инициализации, конструктор копирования, деструктор C++
Конструктор копий C++
Конструктор копирования и перегрузка оператора присваивания C++

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

Или воспользуйтесь поиском по форуму:
FireNovel
 Аватар для FireNovel
150 / 73 / 8
Регистрация: 09.04.2010
Сообщений: 297
06.08.2010, 12:19  [ТС]     Перегрузка оператора ++ , деструктор и конструктор копий #22
Новый вопросец...

А стоит ли организовать поддержку UNICODE? На сколько это актуально?
Если да, то хватит ли переделать используемый тип с char на wchar_t?
Я думал сделать с помощью директив препроцессора и вставить в те места где нужно использовать разные функции, следующий код
( типа
если определен UNICODE
то использовать wchar_t и еарианты функций поднего
Иначе
использовать просто char и еарианты функций поднего
)

Может у кого есть примерчик подобной переделки. Мне бы взглянуть только одним глазком
Yandex
Объявления
06.08.2010, 12:19     Перегрузка оператора ++ , деструктор и конструктор копий
Ответ Создать тему
Опции темы

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