Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.93/14: Рейтинг темы: голосов - 14, средняя оценка - 4.93
 Аватар для FireNovel
150 / 73 / 27
Регистрация: 09.04.2010
Сообщений: 297

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

30.07.2010, 14:34. Показов 3382. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем!

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

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

Пишу 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];
 
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.07.2010, 14:34
Ответы с готовыми решениями:

Почему не вызывается ни конструктор копий, ни функция перегруженного оператора присвоения
Привет. Начал изучать C++, дошел до темы перегрузки операторов. И запарился на одном месте. Есть класс Dog: class Dog { public:...

Конструктор копирования и перегрузка оператора присваивания
Здравствуйте! Возникла следующая проблема: не могу перегрузить оператор присваивания и сделать конструктор копирования Имеется...

Класс "Матрица": конструктор, деструктор и перегрузка операторов
Матрица – KMatrix Методы: конструкторы, деструктор; операции: , =, ==, !=,...

21
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.08.2010, 14:54
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от FireNovel Посмотреть сообщение
Как определить, что класс готов? Ведь, при разработке его, очень часто, в голову лезут разные идеи. И вроде бы и так сделать можно, и эдак - было бы хорошо организовать...
И потихоньку увязаешь в коде
Чтобы не увязать в коде, нужно хорошенько подумать, какие из этих идей ты будешь реально использовать, а без каких можно обойтись.
1
 Аватар для FireNovel
150 / 73 / 27
Регистрация: 09.04.2010
Сообщений: 297
06.08.2010, 12:19  [ТС]
Новый вопросец...

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

Может у кого есть примерчик подобной переделки. Мне бы взглянуть только одним глазком
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.08.2010, 12:19

Определить конструктор без параметров, конструктор с одним параметром, конструктор с двумя параметрами, деструктор
Создать класс «матрица». Данный класс должен содержать элементы типа int, определяющие число строк, столбцов и состояние ошибки. Определить...

Конструктор инициализации, конструктор копирования, деструктор
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор инициализации, конструктор копирования, деструктор....

Создать класс "Вектор" и реализовать конструктор по умолчанию, конструктор копирования и деструктор
Всем доброго времени суток! нужна ваша помощь! нужно создать класс вектор и реализовать конструктор по умолчанию, копирования и...

Конструктор копий
привет, как сделать конструктор копий myclass a(b); value myclass{ private: int a,b; public: myclass(myclass %mc); } ...

Конструктор копий
Добрый день! Пытаюсь разобраться с конструктором копий, а именно: когда его использовать и как реализовать. С первым, вроде как,...


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

Или воспользуйтесь поиском по форуму:
22
Ответ Создать тему
Новые блоги и статьи
BitTorrent (версия 7.11 English) и Меню Настройки
russiannick 15.11.2026
Пункты, отвечающие за отключение обновлений в BitTorrent версии 7. 11 (английской) Options Preferences General Language
Транслитерация текста с кириллицы на латиницу (вариант №4)
Maks 15.11.2026
Что-то я перемудрил с предыдущими версиями, в этот раз сделал всё проще, обратившись к функции "СтрокаЛатиницей" из типового общего модуля "СтроковыеФункцииКлиент". В данной функции нет апострофов,. . .
BitTorrent (версия 4.3.9) и Меню Настройки
russiannick 15.11.2026
В меню Настройки можно отключить автоматическое обновление программы. Карта этого меню приложена ниже. Нужный пункт выделен красным. Сервис Настройки Поведение
Транслитерация текста с кириллицы на латиницу (вариант №3)
Maks 15.11.2026
Обновленная версия предыдущей обработки. Изменения коснулись букв: Ъ, Ы, Ь, Э, отображения которых зависят от положения реквизита "Транслитерация имён". Изменено отображение буквы Й. Добавлена. . .
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru