2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
1

Создание массива объектов класса через список инициализации в конструкторе композита

25.10.2016, 22:07. Показов 6475. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Может, просто плохо искала, но не могу найти. Есть класс, атрибутом которого является массив объектов другого класса. Как составить конструктор класса, чтобы этот массив инициализировать, при том, что объекты классов как атрибуты разрешается (преподом) инициализировать только через список инициализации? Или это невозможно, а я что-то неправильно понимаю?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2016, 22:07
Ответы с готовыми решениями:

Создание динамического массива и его инициализация в конструкторе класса
A1uk, ПравилаИзначальное название темы: "Помогите исправить код". Доброго времени суток. Помоги...

Инициализация объектов класса в конструкторе другого класса
У меня есть класс Subscriber,в котором есть несколько объектов другого класса Date,мне нужно,чтобы...

Создание объектов класса через random
Есть строка кода kot.Add(new kot(r.Next(6) * 40,r.Next(6) * 40)); Как при создании этого объекта...

Создание функции инициализации двумерного массива строк через указатель
Здравствуйте,имеется двумерный массив: in_data_up=_T("00"); in_data_up=_T("01"); ...

16
Эксперт С++
3224 / 1751 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
25.10.2016, 23:07 2
Цитата Сообщение от Nabra Посмотреть сообщение
Может, просто плохо искала, но не могу найти. Есть класс, атрибутом которого является массив объектов другого класса. Как составить конструктор класса, чтобы этот массив инициализировать, при том, что объекты классов как атрибуты разрешается (преподом) инициализировать только через список инициализации? Или это невозможно, а я что-то неправильно понимаю?
Ну, в новом стандарте все нескалярные объекты можно инициализировать через списки инициализации. Ваша задача наверно как раз чтобы в этом потренироваться.
0
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
25.10.2016, 23:24  [ТС] 3
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, в новом стандарте все нескалярные объекты можно инициализировать через списки инициализации. Ваша задача наверно как раз чтобы в этом потренироваться.
А как это реализовать то можно? С инициализацией одного объекта проблем не возникает, вопрос именно в массиве.
0
Эксперт С++
3224 / 1751 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
25.10.2016, 23:27 4
Цитата Сообщение от Nabra Посмотреть сообщение
А как это реализовать то можно? С инициализацией одного объекта проблем не возникает, вопрос именно в массиве.
Ну, приведите свою задачу, а то мы ж не знаем что вы конкретно имеете в виду!
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
25.10.2016, 23:29 5
Nabra,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class B
{
public:
    B(int v) : value(v)
    {}
 
private:
    int value;
};
 
class A
{
public:
    A() : data{1, 2, 3}
    {}
 
private:
    B data[3];
};
http://rextester.com/FAEWU69534
1
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
26.10.2016, 00:33  [ТС] 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#if !defined(__ClassDiagram_UserList_h)
#define __ClassDiagram_UserList_h
 
class User;
 
#include "User.h"
 
class UserList
{
public:
    UserList();
 
   User** user;
 
protected:
private:
   User mUser;
 
 
};
 
#endif
C++
1
2
3
4
5
6
7
8
9
10
#include "User.h"
#include "UserList.h"
#include <iostream>
using namespace std;
 
UserList::UserList()
    :mUser()
{
    cout << "User list created" << endl;
}
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
#if !defined(__ClassDiagram_User_h)
#define __ClassDiagram_User_h
 
#include "Book.h"
 
enum groop { student, lecturer };
 
class User
{
public:
    User();//конструктор за замовченням
 
protected:
private:
   char login[256];
   char bookList[256][10];
   int numberOfBook;
   int numberOfDebts;
   char password[20];
   groop userGroop;
 
 
};
 
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "User.h"
#include <iostream>
 
using namespace std;
 
User::User()
{
    strcpy(login, "\0");
    for (int i = 0; i < 10; i++)
        strcpy(bookList[i], "\0");
    numberOfBook = 0;
    numberOfDebts = 0;
    strcpy(password, "\0");
    userGroop = student;
    cout << "User created" << endl;
}
Кликните здесь для просмотра всего текста
Я, Абрашина Надежда Александровна, даный код предадлежит мне.
У меня паранойя на счет того, что проект после сдачи могут проверить плагиат-тестом, не обращайте внимания.


Сейчас у меня в классе UserList прописан один обьект класса User, но предполагается, что таких объектов будет масив из количества элементов, задаваемого с клавиатуры.

DrOffset, либо я чего-то не понимаю в этом коде, либо это не тот случай. Не ясно, как таким образом можно инициализировать обьект более чем с одной переменной.

Добавлено через 32 минуты
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, приведите свою задачу, а то мы ж не знаем что вы конкретно имеете в виду!
*ответ
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
26.10.2016, 01:09 7
Цитата Сообщение от Nabra Посмотреть сообщение
Не ясно, как таким образом можно инициализировать обьект более чем с одной переменной.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class B
{
public:
    B(int v, char c, const char* s) : value(v), ch(c), str(s)
    {}
 
private:
    int value;
    char ch;
    const char* str;
};
 
class A
{
public:
    A() : data{{1, 'a', "asdf"}, {2, 'b', "qwert"}, {3, 'c', "zxcv"}}
    {}
 
private:
    B data[3];
};
1
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
26.10.2016, 01:14  [ТС] 8
nd2, теперь поняла, спасибо. Но мне это все равно явно не годится (даже если я зафиксирую количество элементов в массиве, оглашать их по одному - это явно плохой стиль).
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.10.2016, 09:37 9
Цитата Сообщение от Nabra Посмотреть сообщение
оглашать их по одному - это явно плохой стиль
Если значения не поддаются выражению через какую-либо формулу, то вполне нормально. Для большого количества элементов можно вызывать приватную функцию инициализации из конструктора.
Однако, большое количество данных лучше хранить не в коде, а, например, получать из файла/БД.
Также, можно использовать std::fill/std::generate.
1
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
26.10.2016, 10:25  [ТС] 10
Цитата Сообщение от MrGluck Посмотреть сообщение
Если значения не поддаются выражению через какую-либо формулу, то вполне нормально. Для большого количества элементов можно вызывать приватную функцию инициализации из конструктора.
Однако, большое количество данных лучше хранить не в коде, а, например, получать из файла/БД.
Также, можно использовать std::fill/std::generate.
К сожалению, я не знаю ни что там будет (инициализировать предполагается через конструктор по умолчанию), ни даже сколько их (хотя если прям без вариантов, могу определить конкретное количество, черт с ним). Работать с базами данных я не умею от слова "совсем". По поводу файлов - подумаю.

Добавлено через 4 минуты
Цитата Сообщение от MrGluck Посмотреть сообщение
std::fill/std::generate
Впервые вижу такую строку.

Добавлено через 22 минуты
Пожалуй, оставлю это извращенство в покое и сделаю файл. Все равно в массиве нужно наперед определять количество элементов, для модели это годится, но в целом нехорошо.
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
26.10.2016, 10:40 11
Цитата Сообщение от Nabra Посмотреть сообщение
К сожалению, я не знаю ни что там будет (инициализировать предполагается через конструктор по умолчанию), ни даже сколько их (хотя если прям без вариантов, могу определить конкретное количество, черт с ним).
Вообще тут все упирается опять же в твое знание языка. Пока что можно сказать, что ответ был дан ровно на то, о чем просили. Т.к. в итоге оказалось, что требуется нечто другое, то вопрос необходимо уточнить.
Вариантов вообще очень много. Просто сейчас твои требования противоречивы. Надо привести все в порядок и решение будет найдено.

Итак, есть задача создавать массив произвольного количества элементов, при этом инициализация должна быть только (почему?) в констукторе по умолчанию? А данные для инициализации этот конструктор сам откуда-то возьмет? При этом и сам массив и данные его элементов нужно обязательно заполнять через список инициализации? В общем, раскрой побольше деталей задачи.

Пока что можно предложить такой вариант:
Кликните здесь для просмотра всего текста
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
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
 
enum groop { student, lecturer };
 
class User
{
public:
    User();
 
protected:
private:
    char login[256];
    char bookList[256][10];
    int numberOfBook;
    int numberOfDebts;
    char password[20];
    groop userGroop;
};
 
User::User()
{
    strcpy(login, "\0");
    for (int i = 0; i < 10; i++)
        strcpy(bookList[i], "\0");
    numberOfBook = 0;
    numberOfDebts = 0;
    strcpy(password, "\0");
    userGroop = student;
    std::cout << "User created" << std::endl;
}
 
class UserList
{
public:
    explicit UserList(size_t count);
 
protected:
private:
    std::vector<User> mUsers;
};
 
UserList::UserList(size_t count)
    : mUsers(count) // создаст count юзеров конструктором по умолчанию
{}
 
int main()
{
    size_t usersCount = 0;
    std::cout << "Input users count: ";
    std::cin >> usersCount;
 
    UserList userList(usersCount);
 
    //.........
}
http://rextester.com/AGNPF98019

Впрочем, все равно необходимо определиться откуда данные будут поступать в случае, если объект создается не по умолчанию.
0
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
26.10.2016, 11:35  [ТС] 12
Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще тут все упирается опять же в твое знание языка.
В том-то и проблема, что знание именно с++ у меня весьма слабые (до этого учила только чистый с).
Четко поставленной задачи у меня нет. Мне нужно составить конструкторы (в проекте), и у меня есть правило, что объект класса в качестве атрибута можно инициализировать тольков списке инициализации. К тому, что мне вообще нужен массив, я пришла сама, теперь начинаю подозревать, что это не совсем так. По поводу конструктора по умолчанию - это была плохая идея, теперь уже понимаю. Я хотела просто создать их пустыми и заполнять через set-функции. Наверное, лучше всего, дествительно, не заморачиватьсяс этими масивами и хранить данные в файлах.
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
26.10.2016, 12:34 13
Цитата Сообщение от Nabra Посмотреть сообщение
Наверное, лучше всего, дествительно, не заморачиватьсяс этими масивами и хранить данные в файлах.
Ну файл-то проблемы до конца не решит. Ведь если с этими данными потом работать в программе, то их нужно будет грузить в какую-то структуру данных.
Если можно пользоваться контейнерами stl, то проще всего представить эти данные в качестве списка или вектора (см. предыдущий пример).

Добавлено через 5 минут
Цитата Сообщение от Nabra Посмотреть сообщение
По поводу конструктора по умолчанию - это была плохая идея, теперь уже понимаю.
Конструктор по умолчанию нужен, но он не должен самостоятельно решать откуда ему тягать данные. Собственно теперь по этой фразе
Цитата Сообщение от Nabra Посмотреть сообщение
Я хотела просто создать их пустыми и заполнять через set-функции.
итак понятно, что этого делать не планировалось. Это нормальный вариант. Если планируется использовать сериализацию в файл, то можно перегрузить операторы << и >> для ввода\вывода из потоков std::istream/std::ostream (внутри могут быть те самые set-функции или запись напрямую в данные класса, если операторы объявлены как friend). Это даст возможность задавать значения как с консоли, так и из файла единообразным способом.
0
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
26.10.2016, 14:01 14
Лучший ответ Сообщение было отмечено Nabra как решение

Решение

Цитата Сообщение от Nabra Посмотреть сообщение
В том-то и проблема, что знание именно с++ у меня весьма слабые (до этого учила только чистый с).
Тогда пора начать использовать std::string и std::vector. Их использовать легко, при этом снимется большая часть проблем.

Для решения твоей задачи достаточно определить конструкторы с правильными типами:

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
#include <cstdint>
#include <string>
#include <vector>
 
class Foo {
public:
  Foo(uint64_t id, const std::string &name)
      : id_(id)
      , name_(name)
  {}
 
private:
  uint64_t id_;
  std::string name_;
};
 
class Bar {
public:
  Bar(const std::vector<Foo> &foos)
      : foos_(foos)
  {}
 
private:
  std::vector<Foo> foos_;
};
Тогда можно легко в коде их создавать:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
  Bar bar1 {{ {1, "ad"}, {2, "cd"}, {3, "bf"} }};
  Bar bar2 ({ {1, "ad"}, {2, "cd"}, {3, "bf"} });
  Bar bar3 = Bar({ {1, "ad"}, {2, "cd"}, {3, "bf"} });
  Bar bar4 = Bar({ Foo(1, "ad"), Foo(2, "cd"), Foo(3, "bf")});
 
  std::vector<Foo> foos5 {{ {1, "ad"}, {2, "cd"}, {3, "bf"} }};
  Bar bar5 (foos5);
 
  std::vector<Foo> foos6;
  foos6.push_back({1, "ad"});
  foos6.push_back({2, "cd"});
  foos6.push_back({3, "bf"});
  Bar bar6 {foos6};
  return 0;
}
З.Ы.: В соответствии с новыми веяниями, конструкторы можно было бы описать так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo {
public:
  template<typename S>
  Foo(uint64_t id, S&& name)
      : id_(id)
      , name_(std::forward<S>(name))
  {}
 
private:
  uint64_t id_;
  std::string name_;
};
 
class Bar {
public:
  template<class C=std::vector<Foo>>
  Bar(C&& foos)
     : foos_(std::forward<C>(foos))
  {}
 
private:
  std::vector<Foo> foos_;
};
но это уже другая история
1
2 / 4 / 3
Регистрация: 08.01.2016
Сообщений: 54
26.10.2016, 14:59  [ТС] 15
Спасибо, по большей части понятно.
То, что их везде по три, это просто совпадение, или это как-то обусловлено кодом?
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.10.2016, 15:11 16
Цитата Сообщение от Nabra Посмотреть сообщение
То, что их везде по три, это просто совпадение, или это как-то обусловлено кодом?
Обусловлено исключительно Ctrl+C, Ctrl+V.
Вектор может хранить кол-во элементов и большее, чем 3.
0
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
26.10.2016, 15:31 17
Цитата Сообщение от Nabra Посмотреть сообщение
То, что их везде по три, это просто совпадение, или это как-то обусловлено кодом?
Содержимое всех шести bar-ов будет одинаковым.
Первые четыре делают одно и тоже. Какой вариант выбирать решать тебе. По мне так 4-й в коде смотрится более читабельным.
0
26.10.2016, 15:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.10.2016, 15:31
Помогаю со студенческими работами здесь

Массив объектов в конструкторе другого класса
есть класс A: class A{ public: double *weights; A() { } A(int a) {

Создание массива объектов класса
Доброго времени суток. Visual Studio 2005(windows form application), вопрос следующий: как создать...

Создание массива объектов класса
Здравствуйте Подскажите пожалуйста как правилььно создать массив объектов класса, что бы не...

Создание массива объектов класса
Создание массива объектов класса. E2451 Undefined symbol 'myZKH' По-разному уже...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru