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

Использование классов в С++. Простые объекты. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.97
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
17.05.2011, 08:55     Использование классов в С++. Простые объекты. #1
Задание:

Описать объект, включающий заданные поля и методы. Написать программу, которая создает массив объектов и список объектов и содержит процедуры, работающие с указанны-ми структурами.
Объект - некоторый товар в магазине. Параметры: наименование, количество и заку-почная цена. Методы: конструктор и процедура, определяющая стоимость товара исходя из заданного процента прибыли. Определить суммарную стоимость всех товаров в магазине. Реализовать два варианта (с массивом и списком).

Написал пока только для списка, с массивом чуть позже напишу. Я создаю класс по заданию, список реализую через структуру ( 1 поле переменная типа класса, 2 поле - указатель ). У меня такой вопрос.
Как получить доступ к полям и методам класса, через указатель ?

Код программы
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
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <conio.h>
 
class List { 
public:
             char name; float amount,price;
 
             List(char n, float a, float p);
             float PriceGood(float profit);
};
 
 
 
List::List(char n, float a, float p)
{ 
    name = n;
    amount = a;
    price = p;
}
 
float List::PriceGood(float profit)
{
    float pr;
    pr = (price*profit*0.01)+price;
    return(pr);
};
 
struct Element 
{
    List Good;
    Element *next;
};
 
 
void main(int argc, char* argv[])
{
     setlocale(0,"russian");
Element Tovar, *first, *cur, *temp;
char tn;
float ta,tp,tprof,sum=0;
int count,i=1;
 
first = NULL;
temp = NULL;
 
puts("Введите кол-во разных товаров и процент прибыли:");
scanf("%d %f",&count,&tprof);
puts("Введите название, кол-во и закупочную стоимость товаров:");
while(i<count){
    printf("%d",i,". ");
    scanf("%s %f %f\n",&tn,&ta,&tp); 
    cur = new Element;
    cur->Good=List::List(tn,ta,tp);
    
    if (first == NULL) 
    {
        first = cur;
        temp = cur;
        cur->next = NULL;
    }
    else 
    {
        temp->next = cur;
        cur->next = NULL; 
    }
}
cur = first;
 
for(i=1;i<count;i++) 
sum+=(cur->Good=List::PriceGood(tprof))*(cur->Good=List.amount);
 
printf("Суммарная стоимость всех товаров в магазине равна : ,%f",sum);
 
puts("Нажмите любую клавишу для завершения...");
     _getch();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.05.2011, 08:55     Использование классов в С++. Простые объекты.
Посмотрите здесь:

C++ Преобразования объектов классов в объекты других классов
Множественное наследование, Перегрузка функций, Перегрузка операторов, Использование дружественных функций и классов, Использование шаблонов классов C++
C++ объекты классов в динамической памяти
C++ как понять: массив указателей на объекты классов?
C++ Классы и объекты 1 - разработка простых классов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.05.2011, 09:03     Использование классов в С++. Простые объекты. #2
1. Принцип инкапсуляции требует, чтобы поля и методы были в приватной части класса.
2. Для получения и изменения полей пишут пару функция get/set - геттеры и сеттеры.
3. p->объект.поле, где p указывает на нужный элемент.
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
17.05.2011, 15:06  [ТС]     Использование классов в С++. Простые объекты. #3
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
1. Принцип инкапсуляции требует, чтобы поля и методы были в приватной части класса.
2. Для получения и изменения полей пишут пару функция get/set - геттеры и сеттеры.
3. p->объект.поле, где p указывает на нужный элемент.
Можете объяснить на примере ?

Добавлено через 1 минуту
П.с.
исправил цикл for
C++
1
2
3
4
for(i=1;i<count;i++) {
sum+=(cur->Good=List::PriceGood(tprof))*(cur->Good=List.amount);
cur=cur->next;
}
Добавлено через 5 часов 37 минут
При компиляции появляется такие ошибки

error C2512: Element: нет подходящего конструктора по умолчанию
error C2352: List::PriceGood: недопустимый вызов нестатической функции-члена
error C2275: List: недопустимое использование этого типа в качестве выражения


Кому не сложно, кто хорошо разбирается в программировании на С++, объясните мне как реализовать доступ к полям объекта и методам класса динамического списка организованного через структуру.
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
17.05.2011, 17:00     Использование классов в С++. Простые объекты. #4
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
1. Принцип инкапсуляции требует, чтобы поля и методы были в приватной части класса.
C++
1
2
private:
  char name; float amount,price;
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Для получения и изменения полей пишут пару функция get/set - геттеры и сеттеры.
Добавь две функции в первой можно передав аргумент установить name, amount, price; в нужные тебе значения, а вторая для получения этих значений, в принципе функция List выполняет задачу set-функции
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
17.05.2011, 17:01     Использование классов в С++. Простые объекты. #5
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Принцип инкапсуляции требует, чтобы поля и методы были в приватной части класса.
Брюс Эккель в книге "Философия С++" ("Thinking in C++") писал о двояком понимании термина инкапсуляция, в общем случае это просто объединения кода и данных в одну логическую единицу (а не сокрытие кода/данных).
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.05.2011, 17:44     Использование классов в С++. Простые объекты. #6
Цитата Сообщение от Kastaneda Посмотреть сообщение
Брюс Эккель в книге "Философия С++" ("Thinking in C++") писал о двояком понимании термина инкапсуляция, в общем случае это просто объединения кода и данных в одну логическую единицу (а не сокрытие кода/данных).
Не-е-е-е-е... Брюс Эккель может писать, что ему угодно.... А Парнас еще в конце 60-х писал об инкапсуляции именно в смысле сокрытия информации. Об этом писал Фредерик Брукс в своей знаменитой книге "Мифический человеко-месяц"... В первом издании он писал, что спорил по этому поводу с Парнасом. А в 90-х годах, когда было переиздание, так и написал: Парнас был прав!
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
17.05.2011, 18:45  [ТС]     Использование классов в С++. Простые объекты. #7
Ребят, неужели ни кто помочь не может ??? Я не прошу решить задачу, прошу только подредактировать фрагмент.

Добавлено через 37 минут
Ну что ж спасибо, за ответы. Не могу сказать они мне сильно помогли, паблик мне не мешал выполнить поставленную задачу, а сет-гет многие вовсе советуют не использовать, да и я не вижу в них особого смысла. Меня больше интересует другой момент, как , при переходе/создании нового структурного элемента (в моем случае это переменная Tovar) через указатель обратиться к функциям и полям.
C++
1
2
cur = new Element; //выделил место под новый элемент
cur->Good=List::List(tn,ta,tp); //теперь мне нужно с помощью конструктора класса дать значения полям класса,который в свою очередь является полем структуры - тут я и озадачен, как это сделать.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.05.2011, 19:04     Использование классов в С++. Простые объекты. #8
1. У тебя в классе Element отсутствует конструктор по умолчанию. Все бы ничего, но у тебя и в классе List отсутствует конструктор по умолчанию! Поэтому и не выходит создать объект - нет конструктора, вызывать нечего!
2. И вызов метода прописан, как статический. А объявлен он как обычный...
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
17.05.2011, 19:10     Использование классов в С++. Простые объекты. #9
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
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cstring>
 
template <class ValueType>
class List {
 private:
  struct Element;
 public:
  // итератор поможет получить последовательный доступ к
  // элементам списка без перебора предыдущих элементов списка.
  class Iterator {
   public:
    explicit Iterator(Element *data) : data_(data) {}
    Iterator() : data_(NULL) {}
    ValueType &operator*() { return data_->data; }
    ValueType &operator->() { return data_->data; }
    Iterator &operator++() {
      data_ = data_->next;
      return *this;
    }
    Iterator operator++(int) {
      Iterator result(data_);
      operator++();
      return result;
    }
    bool operator==(const Iterator &other) {
      return data_ == other.data_;
    }
    bool operator!=(const Iterator &other) {
      return data_ != other.data_;
    }
   private:
    Element *data_;
  };
  Iterator Begin() {
    return Iterator(first_);
  }
  Iterator End() {
    return Iterator(NULL);
  }
  // конец итераторов
 
  List() : size_(0), first_(NULL) {}
  ~List() { Clear(); }
  void Clear() {
    while (first_ != NULL) {
      Element *next = first_->next;
      delete first_;
      first_ = next;
    }
    size_ = 0;
  }
  size_t Size() const { return size_; }
  // добавление в конец списка
  void PushBack(const ValueType &value) {
    Element *last = LastElement();
    if (last == NULL)
      first_ = new Element(value);
    else
      last->next = new Element(last, NULL, value);
    ++size_;
  }
  ValueType &At(size_t position) {
    return ElementAt(position)->data;
  }
 private:
  struct Element {
    ValueType data;
    Element *next;
    Element *prev;
    Element() : prev(NULL), next(NULL) {}
    explicit Element(const ValueType &value)
      : prev(NULL), next(NULL), data(value) {}
    Element(Element *prev_, Element *next_, const ValueType &value)
      : prev(prev_), next(next_), data(value) {}
  };
  Element *ElementAt(size_t position) {
    Element *result = first_;
    while (result != NULL && position-- != 0)
      result = result->next;
    return result;
  }
  Element *LastElement() {
    if (first_ == NULL)
      return NULL;
    Element *result = first_;
    while (result->next != NULL)
      result = result->next;
    return result;
  }
  Element *first_;
  size_t size_;
};
 
class Product {
 public:
  Product() : name_(NULL) {}
  explicit Product(bool) : name_(NULL) {
    char buffer[4] = {0, 0, 0, 0};
    // RAnDoM
    for (int i = 0; i < 3; ++i)
      buffer[i] = rand() % 10 + 'a';
    Name(buffer);
    Count((rand() % 10000) / 100.);
    Price((rand() % 10000) / 100.);
  }
  Product(const Product &other)
    : name_(NULL), count_(other.Count()), price_(other.Price()) {
    Name(other.Name());
  }
  ~Product() {
    delete [] name_;
  }
  void Name(const char *value) {
    delete [] name_;
    name_ = strcpy(new char[strlen(value) + 1], value);
  }
  void Count(float value) { count_ = value; }
  void Price(float value) { price_ = value; }
  char *Name() const { return name_; }
  float Count() const { return count_; }
  float Price() const { return price_; }
  friend std::ostream &operator<<(std::ostream &s, const Product &product) {
    s << "Product: " << product.Name() << std::fixed
      << " X " << product.Count()
      << " X " << product.Price() << " rub." << std::endl;
  }
 private:
  char *name_;
  float count_;
  float price_;
};
 
int main(int argc, char *argv[]) {
  srand(time(NULL));
 
  List<Product> a;
  for (int i = 0; i < 10; ++i)
    a.PushBack(Product(true));
 
  std::cout << a.Size() << std::endl;
  // доступ к элементам массива по позиции.
  // каждый раз идет перебор всех элементов до позиции
  for (int i = 0; i < a.Size(); ++i)
    std::cout << a.At(i);
  std::cout << std::endl;
 
  // получение последовательного доступа при помощи
  // итератора. доступ последовательный.
  for (List<Product>::Iterator j = a.Begin(); j != a.End(); ++j)
    std::cout << *j;
  std::cout << std::endl;
 
  return 0;
}
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
17.05.2011, 19:15  [ТС]     Использование классов в С++. Простые объекты. #10
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
1. У тебя в классе Element отсутствует конструктор по умолчанию. Все бы ничего, но у тебя и в классе List отсутствует конструктор по умолчанию! Поэтому и не выходит создать объект - нет конструктора, вызывать нечего!
2. И вызов метода прописан, как статический. А объявлен он как обычный...
1.Хорошо, как реаизовать конструктор по умолчанию, и чем отличнается по умолчание от не по умолчанию ?

2. В чем разница статического от обычного ? В Лист есть конструктор

C++
1
2
3
4
5
6
List::List(char n, float a, float p)
{ 
        name = n;
    amount = a;
    price = p;
}
Это разве не он ?


Самое понятное объяснение - это наглядный пример. Кто в силах написать 3 строчки кода ? )

Добавлено через 1 минуту
lemegeton, спасибо. Сейчас буду разбирать.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.05.2011, 19:24     Использование классов в С++. Простые объекты. #11
Цитата Сообщение от JmBeats Посмотреть сообщение
Самое понятное объяснение - это наглядный пример. Кто в силах написать 3 строчки кода ? )
Конструктор по умолчанию - это конструктор без аргументов. Если нет такого конструктора, но невозможно создавать объекты без инициализации. А у тебя есть в структуре List Good - без инициализации. Написав собственный конструктор инициализации ты запретил создавать конструктор по умолчанию. Теперь надо самому его написать. Но лучше сделай конструктор инициализации и конструктором по умолчанию:
C++
1
List::List(char n = '\0', float a = 0, float p = 0)
B вопрос: почему имя состоит из ОДНОГО символа?
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
17.05.2011, 20:27  [ТС]     Использование классов в С++. Простые объекты. #12
Что ж спасибо Валерий, с конструктором вроде все ясно, как же быть с указателями и обращением к полям ?

lemegeton, решение напоминает поездку в Москву через Владивосток, не в обиду конечно )), но у меня идет строгое ТЗ. Создать объект с заданными полями и составить список объектов/массив объектов.


п.с. Посоветуйте статью по иерархиям классов в C++.

Добавлено через 1 минуту
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
B вопрос: почему имя состоит из ОДНОГО символа?
А разве имя параметра не может состоять из одного символа ?
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.05.2011, 23:25     Использование классов в С++. Простые объекты. #13
1. Обычно имя - это некий string;
2. Я ж уже писал: p->объект.поле...
К методу: p->объект.метод()
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
17.05.2011, 23:49     Использование классов в С++. Простые объекты. #14
Цитата Сообщение от JmBeats Посмотреть сообщение
решение напоминает поездку в Москву через Владивосток
Надо же. Все, что сложнее a = a + b уже напоминает <нужное вписать>.
Цитата Сообщение от JmBeats Посмотреть сообщение
у меня идет строгое ТЗ. Создать объект с заданными полями и составить список объектов/массив объектов.
"Объект с заданными полями" - class Product, имеется.
Объект, составляющий двусвязный список объектов - class List, имеется, обеспечивает последовательный и случайный доступ к объектам, добавление элементов в конец списка.

Возможно, итераторы сложно понять -- я там спецом пометил, откуда и до куда удалять.

Не обязательно пытаться осмыслить и сдать именно мой код. В коде можно увидеть, как происходит работа со строками, как создавать, удалять связные списки и другие полезные для данной задачи вещи.
JmBeats
0 / 0 / 0
Регистрация: 17.05.2011
Сообщений: 10
19.05.2011, 01:09  [ТС]     Использование классов в С++. Простые объекты. #15
Цитата Сообщение от lemegeton Посмотреть сообщение
Надо же. Все, что сложнее a = a + b уже напоминает <нужное вписать>.

"Объект с заданными полями" - class Product, имеется.
Объект, составляющий двусвязный список объектов - class List, имеется, обеспечивает последовательный и случайный доступ к объектам, добавление элементов в конец списка.

Возможно, итераторы сложно понять -- я там спецом пометил, откуда и до куда удалять.

Не обязательно пытаться осмыслить и сдать именно мой код. В коде можно увидеть, как происходит работа со строками, как создавать, удалять связные списки и другие полезные для данной задачи вещи.
Разобрал, оказывается достаточно грамотно все описано )) , еще раз спасибо )), код использовал "как обучающий". Если кому то будет интересно, чуть позже выложу свою версию программы с наглядным использованием наследования и сложного полиморфизма Всем удачи !

Добавлено через 14 минут
Сейчас попытался скомпилировать, выпадает ошибка
error C4716: operator<<: должна возвращать значение (130 строка)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.05.2011, 02:23     Использование классов в С++. Простые объекты.
Еще ссылки по теме:

C++ Где создавать объекты классов?
Указатель на объекты и члены классов C++
C++ Не получается создать объекты шаблонных классов

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

Или воспользуйтесь поиском по форуму:
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
19.05.2011, 02:23     Использование классов в С++. Простые объекты. #16
здесь забыли вернуть поток
C++
1
2
3
4
5
6
  friend std::ostream &operator<<(std::ostream &s, const Product &product) {
    s << "Product: " << product.Name() << std::fixed
      << " X " << product.Count()
      << " X " << product.Price() << " rub." << std::endl;
      return s;
  }
Yandex
Объявления
19.05.2011, 02:23     Использование классов в С++. Простые объекты.
Ответ Создать тему
Опции темы

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