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

Инкапсуляция. Классы и их компоненты. Объекты - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.94
Novichok92
2 / 2 / 0
Регистрация: 06.10.2009
Сообщений: 39
09.09.2010, 15:45     Инкапсуляция. Классы и их компоненты. Объекты #1
Здравствуйте.
Помогите пожалуйста.Вот есть у меня задание:

Разработать класс, инкапсулирующий свойства одномерного динамического массива заданного размера, например, строку. Тип массива: Знаковый символьный массив.
Для организации динамического массива должен использоваться указатель соответствующего типа. Для хранения размера массива следует предусмотреть соответствующее поле, тип которого можно выбрать самостоятельно.
В классе предусмотреть функции, выполняющие следующие действия:
1.выделение памяти для динамического массива;
2.ввод данных в каждое поле;
3.вывод данных из каждого поля;
4.доступ по считыванию/записи в выбранный элемент массива;
5.освобождение памяти, занятой динамическим массивом.

И есть написанный код:

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
// CLS.H
 
class SIntArray
{
short int len, *arr;
 
public:
        void SetArr();
        void Input();
        void Output();
        void Delete();
        void OutputN();
};
 
 
// FUNC.CPP
 
#include <iostream.h>
#include "cls.h"
 
void SIntArray::SetArr()
{
 cout<<"Vvedite razmer massiva: ";
 cin>>len;
 arr = new short int[len];
 return;
}
 
void SIntArray::Input()
{
 cout<<"Vvedite dannie: \n";
 for(int i = 0; i < len; i++)
 {
  cout <<"A["<<i<<"] = ";
  cin >> arr[i];
 }
}
 
void SIntArray::Output()
{   
 cout << "Massiv: \n";
 for(int i = 0; i < len; i++)   
  cout <<"A["<<i<<"] = "<<arr[i]<<";\n";
}
 
void SIntArray::OutputN()
{
 cout << "Vivod elementa massiva: "; 
 int nom;
 cin >> nom;
 cout << "A["<<nom<<"] = "<<arr[nom]<<";\n";
}
 
void SIntArray::Delete()
{ 
 delete[] arr; 
 cout << "Massiv ydalen \n";
}
 
 
// PROJ1.CPP
 
#include <iostream.h>
#include "FUNC.cpp"
 
int main()
{
 SIntArray a;
  a.SetArr();
  a.Input();
  a.Output();
  a.OutputN();
  a.Delete();
 
 SIntArray* b;  
 int i;
 b = new SIntArray[i]; 
  b[i].SetArr();
  b[i].Input();
  b[i].Output();
  b[i].OutputN();
  b[i].Delete(); 
 delete[] b;
 
 SIntArray c[1];
  int k;
  c[k].SetArr();
  c[k].Input();
  c[k].Output();
  c[k].OutputN();
  c[k].Delete();
 
 SIntArray *d;
 {
  d = new SIntArray;
  d->SetArr();
  d->Input();
  d->Output();
  d->OutputN();
  d->Delete();
 }
 char e;
 cin>>e;
 return 0;
}
Подскажите он правильно написан?И что вообще там делает каждая строчка.
Я вообще то очень плохо там что-то понимаю
Заранее большое спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2010, 15:45     Инкапсуляция. Классы и их компоненты. Объекты
Посмотрите здесь:

C++ классы и объекты
C++ объекты и классы
C++ Объекты и классы в С++
Классы и объекты C++
C++ Классы и объекты
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
10.09.2010, 07:05     Инкапсуляция. Классы и их компоненты. Объекты #2
Код ужасен... Где Вы его раздобыли? Вот более правильная реализация:
arr.hpp:
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
// Объявление класса iarray
 
#ifndef ARR_HPP
#define ARR_HPP
 
#include <iostream>
 
class iarray
{
 
public: // Публичные методы
    
    // Конструкторы - управляют инициализацией объектов класса
    iarray(size_t size = DEFAULT_SIZE);
    iarray(size_t size, const int* array);
    // Деструкторы - управляют зачисткой объектов класса
    ~iarray();
    
    // Ввод данных
    void setArray(int* array);
    // Вывод массива (константый метод)
    const int* getArray() const;
    // Вывод размера массива (константный метод)
    size_t size() const;
    
    // Перегруженный оператор доступа по индексу
    int& operator [] (size_t index);
    // Перегруженный дружественный оператор вывода в поток
    friend std::ostream& operator << (std::ostream& os, const iarray& rhs);
    
private: // Закрытые данные
    
    size_t  m_nSize; // Размер массива
    int*    m_pArr; // Массив
    static const size_t DEFAULT_SIZE = 10; // Значение по умолчанию для размера
};
 
#endif
arr.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
// Реализация класса iarray
 
#include "arr.hpp"
 
#include <stdexcept>
 
iarray::iarray(size_t size)
    : m_nSize(size)
{
    m_pArr = new int[m_nSize];
}
 
iarray::iarray(size_t size, const int* array)
    : m_nSize(size)
{
    m_pArr = new int[m_nSize];
    for(size_t i = 0; i < m_nSize; ++i)
        m_pArr[i] = array[i];
}
 
iarray::~iarray()
{
    delete[] m_pArr;
}
 
void iarray::setArray(int* array)
{
    for(size_t i = 0; i < m_nSize; ++i)
        m_pArr[i] = array[i];
}
 
const int* iarray::getArray() const
{
    return m_pArr;
}
 
size_t iarray::size() const
{
    return m_nSize;
}
 
int& iarray::operator [] (size_t index)
{
    if(index >= m_nSize) // Если индекс превышает максимально допустимый...
        throw std::runtime_error("Index is out of range"); // ...то выбрасывается исключение
    return m_pArr[index];
}
 
std::ostream& operator << (std::ostream& os, const iarray& rhs)
{
    for(size_t i = 0; i < rhs.m_nSize; ++i)
        os << "#" << i + 1 << " -> " << rhs.m_pArr[i] << std::endl;
    return os;
}
main.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
// Пример использования разработанного класса
 
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "arr.hpp"
 
int main()
{
    srand(static_cast<size_t>(time(NULL)));
    size_t sz = 15;
    iarray a1(sz);
    for(size_t i = 0; i < a1.size(); ++i)
        a1[i] = rand() % sz + sz;
    const int* a2 = a1.getArray();
    std::cout << "Generated array:\n( ";
    for(size_t i = 0; i < a1.size(); ++i)
        std::cout << a2[i] << " ";
    std::cout << ")" << std::endl;
    iarray a3(a1.size(), a2);
    std::cout << a3;
    return EXIT_SUCCESS;
}
Novichok92
2 / 2 / 0
Регистрация: 06.10.2009
Сообщений: 39
10.09.2010, 13:35  [ТС]     Инкапсуляция. Классы и их компоненты. Объекты #3
Спасибо большое. Но ваш код что-то очень сложный.Может просто я совсем ничего не понимаю,но старый код я хоть немного понимала.
А тот код вообще не правильный?
Тут вот еще есть доп. задание:
В функции main() создать автоматический объект разработанного класса, указатель на объект, динамический объект и массив объектов (из 3-4 элементов).
4. Для каждого созданного объекта выполнить по очереди функции ввода размера массива, выделения памяти, ввода данных в массив, вывода данных на экран, вывода одного из элементов массива и освобождения памяти.
5. Модифицировать текст программы следующим образом: в любом месте функции main() создать блок (составной оператор), внутри которого создать объект класса и выполнить для него ввод данных. Попытаться получить доступ к объекту за пределами блока, например, вывести его данные.

Я так понимаю это соответствует коду:
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
int main()
{
 SIntArray a;
  a.SetArr();
  a.Input();
  a.Output();
  a.OutputN();
  a.Delete();
 
 SIntArray* b;  
 int i;
 b = new SIntArray[i]; 
  b[i].SetArr();
  b[i].Input();
  b[i].Output();
  b[i].OutputN();
  b[i].Delete(); 
 delete[] b;
 
 SIntArray c[1];
  int k;
  c[k].SetArr();
  c[k].Input();
  c[k].Output();
  c[k].OutputN();
  c[k].Delete();
 
 SIntArray *d;
 {
  d = new SIntArray;
  d->SetArr();
  d->Input();
  d->Output();
  d->OutputN();
  d->Delete();
 }
 char e;
 cin>>e;
 return 0;
}
Но что там я вообще не понимаю и для чего. Этот код соответствует заданию?Подскажите пожалуйста
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
10.09.2010, 14:33     Инкапсуляция. Классы и их компоненты. Объекты #4
Цитата Сообщение от Novichok92 Посмотреть сообщение
А тот код вообще не правильный?
Сейчас пройдемся по недостаткам приведенного выше кода:
  1. Для управления инициализацией и очисткой объектов существуют специальные методы - конструкторы и деструкторы (у Вас их роль играют методы SetArr и Delete соответственно). Для чего нужна инициализация объектов в конструкторе? Для того, чтобы предотвратить доступ к неинициализированным данным-членам класса. Даже если нужно, чтобы заполнение массива происходило не в момент создания объекта класса, то все равно хорошо было бы объявить конструктор по умолчанию для инициализации данных класса нулевыми значениями. Зачем нужен деструктор? Затем, что он автоматически вызывается, когда уничтожается объект. Т.е., если зачисткой данных у Вас занимается не деструктор, а другой метод, то необходимо явно вызывать его перед уничтожением объекта. Забыли это сделать - получили утечку памяти
  2. Внутри методов класса не принято организовывать взаимодействие с пользователем (т.е. обращение к потокам ввода-вывода). Вот навскидку несколько причин для этого. Во-первых, каждый раз, когда Вы собираетесь менять формат ввода-вывода данных Вашего класса, Вам необходимо менять реализацию класса. Во-вторых, представьте, что Вам нужно использовать Ваш класс в программе с графическим интерфейсом, которая никак не взаимодействует с консолью. В этом случае Ваш класс будет абсолютно бесполезен и Вам опять придется его переписывать.
    Так что оптимальная стратегия - это передача конструктору класса уже имеющихся данных, на основе которых он и построит объект класса. Альтернатива - перегрузка операторов ввода-вывода, но этим увлекаться тоже нельзя, т.к. случаи, когда они действительно повышают удобство/гибкость прогаммы, встречаются достаточно редко (яркий пример - для большинства контейнеров STL они не определены).
Цитата Сообщение от Novichok92 Посмотреть сообщение
Но что там я вообще не понимаю и для чего. Этот код соответствует заданию?
Он соответсвует только части задания, а именно:
Цитата Сообщение от Novichok92 Посмотреть сообщение
Для каждого созданного объекта выполнить по очереди функции ввода размера массива, выделения памяти, ввода данных в массив, вывода данных на экран, вывода одного из элементов массива и освобождения памяти.
и
Цитата Сообщение от Novichok92 Посмотреть сообщение
В функции main() создать автоматический объект разработанного класса, динамический объект и (формально) массив объектов (из 3-4 элементов).
А еще этот код содержит грубую ошибку: для задания размера массива используется неинициализированная переменная, значение которой не определено.

Создания указателя на (существующий) объект и объекта с областью видимости и контекстом внутреннего блока - нет.

Вот так может выглядеть дополнительное задание с моим классом:
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
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "arr.hpp"
 
void randomArray(int* iarr, size_t sz)
{
    for(size_t i = 0; i < sz; ++i)
        iarr[i] = rand() % sz + sz;
}
 
int main()
{
    srand(static_cast<size_t>(time(NULL)));
    const size_t n = 8;
    int initArr[n];
    
    // Автоматический объект
    randomArray(initArr, n);
    iarray autoArr(n, initArr);
    std::cout << autoArr << std::endl;
    
    // Указатель на существующий объект
    iarray* pautoArr = &autoArr;
    // Можно повторно его инициализировать
    randomArray(initArr, n);
    pautoArr->setArray(initArr);
    std::cout << (*pautoArr) << std::endl;
    
    // Динамический объект
    randomArray(initArr, n);
    iarray* pdynArr = new iarray(n, initArr);
    std::cout << (*pdynArr) << std::endl;
    // Деструктор динамического объекта нужно вызывать явно:
    delete pdynArr;
    
    // Массив объектов
    iarray arr3[3];
    for(size_t i = 0; i < 3; ++i)
    {
        randomArray(initArr, n);
        arr3[i].resize(n); // Нужно написать метод resize
        arr3[i].setArray(initArr);
        std::cout << "#" << i + 1 << std::endl << arr[i] << std::endl;
    }
        
    // Объект внутри блока
    {
        randomArray(initArr, n);
        iarray inside(n, initArr);
        std::cout << inside << std::endl;
    }
    // std::cout << inside << std::endl; -- ошибка! - здесь объект уже не существует
    return EXIT_SUCCESS;
}
Novichok92
2 / 2 / 0
Регистрация: 06.10.2009
Сообщений: 39
10.09.2010, 15:03  [ТС]     Инкапсуляция. Классы и их компоненты. Объекты #5
Спасибо большое за объяснения недостаток кода.
Именно в этом примере сказали не использовать конструктуры и деструкторы (они будут далее) и сделать все по проще.
А насчет переменной для хранения размера массива:
Для хранения размера массива следует предусмотреть соответствующее поле, тип которого можно выбрать самостоятельно
Ничего про определение его точного размера нет.
Большое спсибо за написанный код.Попробую его понять.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
10.09.2010, 15:12     Инкапсуляция. Классы и их компоненты. Объекты #6
Цитата Сообщение от Novichok92 Посмотреть сообщение
А насчет переменной для хранения размера массива:
Для хранения размера массива следует предусмотреть соответствующее поле, тип которого можно выбрать самостоятельно
Я выразился немного неточно:
Цитата Сообщение от Nameless One Посмотреть сообщение
А еще этот код содержит грубую ошибку: для задания размера массива используется неинициализированная переменная, значение которой не определено.
- под массивом здесь подразумевается не внутренний массив разрабатываемого класса, а массив объктов этого класса. То есть этот код - ошибочный:
C++
1
2
3
4
5
 SIntArray* b;  
 int i; // Переменная i - неинициализирована, в ней хранится "мусор"
 b = new SIntArray[i]; 
  // ...
 delete[] b;
Novichok92
2 / 2 / 0
Регистрация: 06.10.2009
Сообщений: 39
10.09.2010, 17:45  [ТС]     Инкапсуляция. Классы и их компоненты. Объекты #7
Есть еще небольшой вопрос:а в какой программе вы пишите?
У меня в Dev C++ вылетает ошибка на строчке
arr3[i].resize(n);
'class iarray' has no member named 'resize'
`arr' undeclared (first use this function)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.09.2010, 17:48     Инкапсуляция. Классы и их компоненты. Объекты
Еще ссылки по теме:

C++ Инкапсуляция. классы
C++ классы и объекты С++
C++ Классы и объекты в С++

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

Или воспользуйтесь поиском по форуму:
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1330 / 863 / 50
Регистрация: 02.01.2009
Сообщений: 2,621
Записей в блоге: 1
10.09.2010, 17:48     Инкапсуляция. Классы и их компоненты. Объекты #8
У меня в Dev C++ вылетает ошибка на строчке
arr3[i].resize(n);
'class iarray' has no member named 'resize'
`arr' undeclared (first use this function)
Внимательно читай комментарий...
Цитата Сообщение от Nameless One Посмотреть сообщение
arr3[i].resize(n); // Нужно написать метод resize
Yandex
Объявления
10.09.2010, 17:48     Инкапсуляция. Классы и их компоненты. Объекты
Ответ Создать тему
Опции темы

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