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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
#1

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

19.06.2016, 09:54. Просмотров 316. Ответов 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";
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.06.2016, 09:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос создание объекта класса в методе этого же класса (C++):

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

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

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

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

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! - C++
Друзья! Почему так? #include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace std; //Вот главный класс class A{ ...

Приём константных векторов класса, как аргументов в методе другого класса - C++
Есть такой класс: class Order { private: int numberOrder; map &lt;string, int&gt; catalogDish; double totalCost; public: ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nmcf
5309 / 4629 / 1548
Регистрация: 14.04.2014
Сообщений: 18,437
19.06.2016, 10:19 #2
Цитата Сообщение от DimaAvatar Посмотреть сообщение
можно ли создавать объект класса в методе того же класса?
Можно.
Цитата Сообщение от DimaAvatar Посмотреть сообщение
я создаю объект класса в самом классе и sizeof определяю его размер
sizeof() не применим к твоему классу (так же как и запись объекта целиком). Т. е. это скомпилируется, но результат будет не тот, который ты ожидаешь. Исправь сначала это.
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 11:05  [ТС] #3
Цитата Сообщение от nmcf Посмотреть сообщение
Можно.

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

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

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

Использование древних строк создаст свои сложности - с выделением памяти, или с ограниченной длинной для массива, невозможностью сравнивать простыми операциями. В общем делай запись отдельных полей, она ничем не отличается от записи целиком, только длину не забудь для string.
эм, да, а разве не в этом смысл бинарного файла? нет? я думал что как раз да - берез объект эм, или структуру (но в моем случае объект класса) и пишешь его в бинарный файл, что избавляет от разбора строки и инициализации полей объекта при текстовом формате, я не правильно понимаю назначение бинарного способа записи/чтения? Не могли бы подсказать тогда?
а то я начал читать доки по boost эм, видимо, мое кунг-фу еще не совсем кунг фу (((
nmcf
5309 / 4629 / 1548
Регистрация: 14.04.2014
Сообщений: 18,437
19.06.2016, 14:45 #13
Бинарный, значит копируется внутреннее представление из памяти в файл. Но если твой класс не хранится в непрерывной области, а в нескольких разных, то и запись должна это учитывать.
Цитата Сообщение от 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);
DimaAvatar
0 / 0 / 0
Регистрация: 05.02.2014
Сообщений: 141
19.06.2016, 14:49  [ТС] #14
Цитата Сообщение от nmcf Посмотреть сообщение
Бинарный, значит копируется внутреннее представление из памяти в файл. Но если твой класс не хранится в непрерывной области, а в нескольких разных, то и запись должна это учитывать.
эм, а как понять храниться мой класс в непрерывной области или нет? что есть непрерывная область? Как узнать что он в нескольких областях? и эм.. как это должна учитывать запись? эм да, я пока совсем потерял нить объяснения...
nmcf
5309 / 4629 / 1548
Регистрация: 14.04.2014
Сообщений: 18,437
19.06.2016, 15:00 #15
Я же сказал - простые типы будут прямо в классе, а контейнеры STL, типа string и vector, используют динамическую память для хранения содержимого. Или если указатель будет в классе - прямой записью ты просто адрес сохранишь, а не содержимое.

Добавлено через 2 минуты
У тебя 4 поля: 3 string и 1 float. Каждый string записываешь по образцу выше, и в конец дописываешь float. Чтение через vector или через массив.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.06.2016, 15:00
Привет! Вот еще темы с ответами:

Ошибка при вызове метода класса в методе другого класса - C++
Господа программисты, возникла такая проблема. При вызове метода класса в методе другого класса выходит такая ошибка &quot; нестандартный...

Как в методе класса вызвать другой метод того же класса? - C++
class mate { public: int AplusB(int A, int B) { return A+B; } int AplusBplusC(int A, int B, int C)

Задачка для новичков #2: вывести в методе класса-родителя значение данных-членов из дочернего класса - C++
Вдохновленный соседней темой тоже решил задать свой вопрос таким же начинающим программистам как и я :) Все кто хочет попробовать дать...

Создать объект внутри класса, который может вызывать функцию этого класса - C++
Ребята помогите уже несколько дней мучаюсь. Хочу сделать программу в консоле демонстрации работы лифта в здании 2 этажа. Сделал класс...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
19.06.2016, 15:00
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru