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

Создание объекта класса в методе этого же класса

19.06.2016, 09:54. Показов 6708. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
собственно вопрос. можно ли создавать объект класса в методе того же класса? насколько это правильно и как это можно сделать (если это правильно) или же как этого не делать (если это не правильно)
суть проблемы. пользователь вводит марку модель продукта и его кол-ва преступаемого на склад. эти данные принимаются методом класса, далее происходит проверка есть ли в бинарном файле объект с подобными характеристиками - если есть - изменить кол-во уже имеющегося объекта, если же нет, различаеться марка или модель товара - записать объект в файл. для чтения бинарного файла мне необходим размер объекта, для этого я создаю объект класса в самом классе и sizeof определяю его размер. вообще я даже не уверен, что в этом ошибка, программа аварийно завершается, valgrind я читаю с большим трудом (да ладно врать то, вообще не понимаю чего он мне пишет)) но а) все таки хотелось бы понять делают ли так б) может ткнете еще носом где я накосячил?? Спасибо братья )))


wire.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef WIRE_H
#define WIRE_H
#include "goods.h"
 
using namespace std;
 
 
class wire:public virtual goods {
    protected:
        string product;
        string brand;
        string model;
        float amount;
 
    public:
     wire(){};
     void compare(wire&);
     void show();
     void set(string&,string&,string&,string&);
     void new_write(wire&);
};
#endif // WIRE_H
wire.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
#include "wire.h"   // подключаем заголовочный файл
#include <cstring>  // для операций над string
#include <fstream>  // для открытия и чтнния файла
#include <iomanip>  // std::setw для форматированного вывод
#include <cstdlib>
#include <iostream>
 
using namespace std;
 
/*здесь метод set принимает аргументы из main */
void wire::set(string& prod,string& br,string& mod,string& am){
    product  = prod;
    brand = br;
    model = mod;
    amount = atof(am.c_str());
 
    int count = 0;//count для проверки файла на отсутствие объектов
    
    wire temp; // !!!!создаю объект класса в этом же классе!!!!
    
    ifstream file;
    file.open("/home/dima/QT_CPP/my_project/binary/goods.txt",ios::in | ios::binary);
    if (!file.is_open()){
        cout<<"<База данных не обноруженна проверьте верность указания пути\n";
    } else {
        /*вот эта строчка из за которой я вынужден создавать объект класса в классе*/
        while(file.read((char*)&temp,sizeof(temp))){
            file.read((char*)&temp,sizeof(temp));;
            compare(temp); // считанный объект сравнить
            ++count;
        }
    }
    file.close();
    file.clear();//без сброса флагов ошибок работать не будет
 
    /*если файл пустой - записать объект*/
    if (count == 0 ) new_write(temp);
}
 
/*здесь происходит сравнение объекта, если совпадение марки и модели то передать объект в метод, где будет увеличенно
 * кол-во (сумма поступления товара и того, что уже было). метод прибавления пока не реализован, в ином случае - записать
 * объект как новый*/
 
void wire::compare(wire&temp){
    if (temp.brand == brand && temp.model == model);
    else new_write(temp);
}
 
/*здесь я присваиваю полям временного объекта  temp значения полученные из main и записываю объект в конец файла*/
void wire::new_write(wire&temp){
    temp.product = product;
    temp.brand = brand;
    temp.model = model;
    temp.amount = amount;
 
    ofstream file;
    file.open("/home/dima/QT_CPP/my_project/binary/goods.txt",ios::out | ios::app | ios::binary);
    if (!file.is_open()){
        cout<<"<База данных не обноружена проверьте верность указания пути\n";
    } else {
        file.write((char*)&temp,sizeof(temp));
    }
    file.close();
    file.clear();//без сброса флагов ошибок работать не будет
}
/*метод show - показывает, что есть поля объекта*/
void wire::show(){
    cout<<product<<" "<<brand<<" "<<model<<" "<<amount<<"\n";
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.06.2016, 09:54
Ответы с готовыми решениями:

Возможно ли создание объекта шаблонного класса в функции этого класса?
Доброго времени суток, уважаемые форумчане :) Мне по лабам задали задание - реализовать шаблон контейнера (множество) с операциями...

Вызов метода класса в лямбде-функции, вызываемой в другом методе этого же класса
Здравствуйте. Помогите грамотно передать в лямбду метод класса. Упрощенно. Есть класс. В одном методе этого класса вызывается...

Указатель метода класса в другом методе этого класса
Здравствуйте. Как можно передать в методе класса указатель на другой метод этого же класса. Задача сделать вот что: class A { ...

16
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.06.2016, 10:19
Цитата Сообщение от DimaAvatar Посмотреть сообщение
можно ли создавать объект класса в методе того же класса?
Можно.
Цитата Сообщение от DimaAvatar Посмотреть сообщение
я создаю объект класса в самом классе и sizeof определяю его размер
sizeof() не применим к твоему классу (так же как и запись объекта целиком). Т. е. это скомпилируется, но результат будет не тот, который ты ожидаешь. Исправь сначала это.
0
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 11:05  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Можно.

sizeof() не применим к твоему классу (так же как и запись объекта целиком). Т. е. это скомпилируется, но результат будет не тот, который ты ожидаешь. Исправь сначала это.
эм, не совсем понимаю почему sizeof не применим??? у Лафоре и на просторах тырнета я находил именно такой способ записи объектов в бинарные файлы? эм, исправить что и на что... просто другого способа записи объекта я пока не знаю. Не могли бы подсказать, чем плохо выбранный мною метод?

Добавлено через 9 минут
эм... или вы имеете в виду необходимость делать, эм... рпеобразование типа путем применения reinterpret_cast???

Добавлено через 16 минут
или же вы намекаете на необходимость изучения сериализации данных? мне бы просто понять куда копать и почему sizeof мне не подходит?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.06.2016, 11:43
sizeof применим, если в классе простые типы: int, char и т. п. А если там классы использующие динамическую память, контейнеры, то записывать нужно индивидуально. Для string записывается количество символов и содержимое.
В общем будет несколько read()/write() для твоего класса.
1
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 11:59  [ТС]
эм, т.е. если я изменю тип данных полей класса с string на char* это избавит меня от пока не доступных мне танцов с бубном?
0
184 / 192 / 48
Регистрация: 25.08.2011
Сообщений: 792
19.06.2016, 12:18
Здравствуйте. Нет не избавит sizeof(char*) = 4 при 32 битах в не зависимости от данных на которые он указывает
0
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 12:22  [ТС]
Цитата Сообщение от 1Вирт1 Посмотреть сообщение
Здравствуйте. Нет не избавит sizeof(char*) = 4 при 32 битах в не зависимости от данных на которые он указывает
эм, я пытаюсь понять пути выхода из ситуации... эм? boost::serialization ? мне бы что нибудь попробще, я с stl то еще не разобрался, не то, что с boost
0
184 / 192 / 48
Регистрация: 25.08.2011
Сообщений: 792
19.06.2016, 12:26
попробуйте перегрузить ofstream& operator<<(); и использовать его. Ну или же писать членны данные в файл отдельно
1
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 12:31  [ТС]
Цитата Сообщение от 1Вирт1 Посмотреть сообщение
попробуйте перегрузить ofstream& operator<<(); и использовать его. Ну или же писать членны данные в файл отдельно
писать отдельно? тогда суть использовать бинарного файла? не проще ли будет использовать просто тектовый доступ? но в текстовом варианте я уже реализовывал, мне бы хотелось разобраться именно с бинарным и с использованием его преимущества перед текстовым вариантом - т.е. возможность записывать объекты класса. Но все равно спасибо )))
0
184 / 192 / 48
Регистрация: 25.08.2011
Сообщений: 792
19.06.2016, 13:00
ем я просто сомниваюсь что у вас выйдет string написать без почленной записи. поможет если заменить string на char[] со статической длинной. но это плохое решение. при сереализации скорее все го бы был выбран некий формат данных аля длина строки - строка и т.д.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.06.2016, 13:27
Цитата Сообщение от DimaAvatar Посмотреть сообщение
тогда суть использовать бинарного файла?
Для тебя бинарный, это если объект целиком записывается, что ли?
Цитата Сообщение от DimaAvatar Посмотреть сообщение
если я изменю тип данных полей класса с string на char*
Использование древних строк создаст свои сложности - с выделением памяти, или с ограниченной длинной для массива, невозможностью сравнивать простыми операциями. В общем делай запись отдельных полей, она ничем не отличается от записи целиком, только длину не забудь для string.
0
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 14:17  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Для тебя бинарный, это если объект целиком записывается, что ли?

Использование древних строк создаст свои сложности - с выделением памяти, или с ограниченной длинной для массива, невозможностью сравнивать простыми операциями. В общем делай запись отдельных полей, она ничем не отличается от записи целиком, только длину не забудь для string.
эм, да, а разве не в этом смысл бинарного файла? нет? я думал что как раз да - берез объект эм, или структуру (но в моем случае объект класса) и пишешь его в бинарный файл, что избавляет от разбора строки и инициализации полей объекта при текстовом формате, я не правильно понимаю назначение бинарного способа записи/чтения? Не могли бы подсказать тогда?
а то я начал читать доки по boost эм, видимо, мое кунг-фу еще не совсем кунг фу (((
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.06.2016, 14:45
Бинарный, значит копируется внутреннее представление из памяти в файл. Но если твой класс не хранится в непрерывной области, а в нескольких разных, то и запись должна это учитывать.
Цитата Сообщение от DimaAvatar Посмотреть сообщение
что избавляет от разбора строки
Тебе не надо ничего разбирать. Пример:
C++
1
2
3
4
string s;
size_t n = s.length();
file.write(reinterpret_cast<char *>(&n), sizeof(n));
file.write(s.c_str(), n);
1
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 14:49  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Бинарный, значит копируется внутреннее представление из памяти в файл. Но если твой класс не хранится в непрерывной области, а в нескольких разных, то и запись должна это учитывать.
эм, а как понять храниться мой класс в непрерывной области или нет? что есть непрерывная область? Как узнать что он в нескольких областях? и эм.. как это должна учитывать запись? эм да, я пока совсем потерял нить объяснения...
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.06.2016, 15:00
Я же сказал - простые типы будут прямо в классе, а контейнеры STL, типа string и vector, используют динамическую память для хранения содержимого. Или если указатель будет в классе - прямой записью ты просто адрес сохранишь, а не содержимое.

Добавлено через 2 минуты
У тебя 4 поля: 3 string и 1 float. Каждый string записываешь по образцу выше, и в конец дописываешь float. Чтение через vector или через массив.
1
0 / 0 / 1
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 15:21  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Я же сказал - простые типы будут прямо в классе, а контейнеры STL, типа string и vector, используют динамическую память для хранения содержимого. Или если указатель будет в классе - прямой записью ты просто адрес сохранишь, а не содержимое.

Добавлено через 2 минуты
У тебя 4 поля: 3 string и 1 float. Каждый string записываешь по образцу выше, и в конец дописываешь float. Чтение через vector или через массив.
а... я пропустил Ваш код. сейчас буду тупить разбираться. Спасибо
0
 Аватар для vlisp
1064 / 985 / 153
Регистрация: 10.08.2015
Сообщений: 5,365
19.06.2016, 18:42
Цитата Сообщение от DimaAvatar Посмотреть сообщение
пользователь вводит марку модель продукта и его кол-ва преступаемого на склад
В этой фразе уже три класса
1) товар
2) приемщик товара
3) склад

2) Принимает товар у поставщика, Проверяет товар на складе, Складирует товар на складе, Выдает товар со склада потребителю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.06.2016, 18:42
Помогаю со студенческими работами здесь

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

Создание статической функции класса, которая принимает экземпляр этого же класса как объект
Привет. Есть такой код class Model { public: Model(); Model(int verticesSize, int facesSize); ~Model(); static void...

Создание объекта класса с полем являющимся объектом другого класса
Bill a; cin&gt;&gt;a;//тут я ввел с помощью перегруженного оператора ElementSpiska c; //поля у Spiska(Bill A,int,string,int) ...

TIdNotify, создание и удаление объекта этого класса
Как правильно использовать компонент TIdNotify, а точнее как правильно создавать/удалять объект этого класса. Искал решение, но так и не...

Инициализация объекта класса объектом этого же класса
В задаче создается объект класса hoba, в который добавляются объекты базового и производного класса, дальше необходимо в новый созданный...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера 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. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru