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

Динамически создать массив

31.01.2013, 05:22. Показов 1034. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Все чуть посложнее, чем кажется.
Goat, Wolf, Cowboy - производные классы от Animal. Динамически создаем массивы из Goat и Wolf. Cowboy - только один. Затем, поскольку у них у всех есть виртуальные функции, которые мне надо использовать, я создаю массив указателей на тип Animal.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
cout<<"How many goats? ";  // Сколько коз в стаде
cin>>numberOfGoats;
Goat *ptrGoats = new Goat[ numberOfGoats ];
 
cout<<"How many wolves: "; // Сколько волков должны напасть
cin>>numberOfWolves;
Wolf *ptrWolves = new Wolf[ numberOfWolves ]; 
 
const int totalAnimals = numberOfWolves + numberOfGoats + 1; // Общее количество животных ( включая пастуха )
 
Animal *ptrAnimals[ totalAnimals ] = ptrGoats; // Вот тут и встает проблема. Если и тут динамически выделить память,
ptrAnimals[ totalAnimals - numberOfWolves ] = ptrWolves;  // то встает другая проблема. О ней ниже.
ptrAnimals[ totalAnimals - 1 ] = &cowboy;
Animal *ptrAnimals[ totalAnimals ] = ptrGoats; можно сделать типа: Animal *ptr = new Animal[ totalAnimals ]; , но в этом случае не получается заставить ptrAnimals указывать на ptrGoats, и на ptrWolves и на Cowboy.
А если этого не сделать, то меня ждет морока в коде и дописывание кучи циклов для каждого производного класса, когда можно все запихнуть в один массив и вызывать их виртуальные функции в одном цикле.

Есть идеи решения этой проблемы?

Добавлено через 4 минуты
И раз пошла такая пьянка, то еще один вопрос:
Есть базовый класс, есть производный класс. В базовом классе есть public функция "Кушать". Она ведь наследуется производному классу, не так ли? Ее не надо объявлять в интерфейсе производного класса или надо?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.01.2013, 05:22
Ответы с готовыми решениями:

Как динамически создать массив из динамически конструируемых экземпляров класса?
Есть два класса.Подразумевается ,что первый в конструкторе выделяет интовый массив длинной n,второй выделяет массив экземпляров первого...

Как создать динамически расширяемый массив объектов пользовательского типа (структура User)?
Здравствуйте, нужна ваша помощь с структурой ... Bот у меня пользователей при регистрации может быть ток 100 , как как сделать, чтоб был...

Как динамически создать ассоциативный массив?
Покажите как создавать динамически ассоциативный массив. Например в скрипте &lt;?php $list=scandir(&quot;./union&quot;); ...

8
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
31.01.2013, 08:51
Цитата Сообщение от eoLithic Посмотреть сообщение
Есть базовый класс, есть производный класс. В базовом классе есть public функция "Кушать". Она ведь наследуется производному классу, не так ли? Ее не надо объявлять в интерфейсе производного класса или надо?
Наследуется. Не надо. Но, если вы захотите её специфицировать и вызвать из базового класса, придется сделать её виртуальной.

Цитата Сообщение от eoLithic Посмотреть сообщение
Есть идеи решения этой проблемы?
Что вам мешает скопировать адреса объектов в новый массив?

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
#include <cstdlib>
#include <ctime>
#include <iostream>
 
class Animal {
 public:
  virtual void eat() = 0; // абстрактная виртуальная функция
};
 
class Wolf : public Animal {
 public:
  virtual void eat() {
    std::cout << "wolf eats" << std::endl;
  }
};
 
class Goat : public Animal {
 public:
  virtual void eat() {
    std::cout << "goat eats" << std::endl;
  }
};
 
// этот ковбой настоящее животное
class Cowboy : public Animal {
 public:
  virtual void eat() {
    std::cout << "cowboy eats" << std::endl;
  }
};
 
int main(int argc, char **argv) {
  srand(time(0));
 
  int numberOfGoats = 5 + rand() % 10;
  Goat *goats = new Goat[numberOfGoats];
 
  int numberOfWolves = 5 + rand() % 10;
  Wolf *wolves = new Wolf[numberOfWolves];
 
  Cowboy *cowboy = new Cowboy();
 
  int numberOfAnimals = numberOfGoats + numberOfWolves + 1;
  // указатель (массив) указателей на животных
  Animal **animals = new Animal*[numberOfAnimals];
  
  int j = 0;
  // кладем в массив _адреса_ животных
  for (int i = 0; i < numberOfGoats; ++i) animals[j++] = goats + i; // aka &(goats[i])
  for (int i = 0; i < numberOfWolves; ++i) animals[j++] = wolves + i; // aka &(wolves[i])
  animals[j++] = cowboy;
 
  // ну и можно пользоваться
  for (int i = 0; i < numberOfAnimals; ++i) {
    animals[i]->eat();
  }
  
  delete [] goats;
  delete [] wolves;
  delete cowboy;
  std::cin.get();
  return 0;
}
1
0 / 0 / 0
Регистрация: 05.01.2013
Сообщений: 32
31.01.2013, 12:26  [ТС]
Допустим
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Animal
{
public:
void setName( string );
string getName() const;
 
private:
string name;
};
 
string Animal::getName()
{   return name;  }
C++
1
2
3
4
5
6
7
class Human : public Animal
{
//Для того, чтобы объекты Human могли пользоваться 
//функцией getName() , реализация которой не отличается 
//от реализации в базовом классе, нужно ли мне объявлять
//getName() в интерфейсе Human.h ?
}
Добавлено через 2 часа 5 минут
Помогите, пожалуйста, еще кое с чем.
Допустим, функцию int AnotherClass::randomPoint() вызывают только объекты SomeClass. Я хочу, чтобы функция randomPoint() проверяла количество очков у объекта SomeClass, вызвавшего ее, и в определенном случае возвращала 100 очков. Хотел использовать указатель this, но он вернет мне адреса объекта object из SomeClass, не так ли?
Как сделать так, чтобы функция randomPoint() проверяла значение points объекта SomeClass, который ее вызвал?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class AnotherClass
{
public:
int randomPoint();
private:
int point;
};
 
int AnotherClass::randomPoint()
{
point = rand() % 10;
return point;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class SomeClass
{
public:
void addPoints();
 
private:
int points;
AnotherClass object;
};
 
void SomeClass::addPoints()
{
points += object.randomPoint;
}
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
31.01.2013, 13:57
Цитата Сообщение от eoLithic Посмотреть сообщение
Хотел использовать указатель this, но он вернет мне адреса объекта object из SomeClass, не так ли?
Так. Добавь метод get для points в классе SomeClass и в функции randomPoints() вызывай что-то типа "ptr->getPoints();", где ptr == this
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
31.01.2013, 14:09
Цитата Сообщение от eoLithic Посмотреть сообщение
//Для того, чтобы объекты Human могли пользоваться
//функцией getName() , реализация которой не отличается
//от реализации в базовом классе, нужно ли мне объявлять
//getName() в интерфейсе Human.h ?
Нет, не нужно.

Цитата Сообщение от eoLithic Посмотреть сообщение
Как сделать так, чтобы функция randomPoint() проверяла значение points объекта SomeClass, который ее вызвал?
С точки зрения архитектуры и универсальности лучше эту логику перекроить так, чтобы только один класс управлял points'ами.
Приведите более конкретный пример, где это необходимо. С SomeClass и AnotherClass я что-то путаюсь и не могу придумать пример.
1
0 / 0 / 0
Регистрация: 05.01.2013
Сообщений: 32
01.02.2013, 00:05  [ТС]
lemegeton,
Пример:
Объект класса Gambler вызывает функцию getCard(). В зависимости от того сколько очков у игрока, функция выдает ему определенное количество очков. Но функция getCard() в своем теле вызывает функцию giveACard() класса KolodaKart и giveACard() должна узнавать сколько очков у объекта типа Gamber, который вызвал ее. В этом и вся проблема.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class KolodaKart
{
public:
void rastasovatKolodu();
int giveACard();
 
private:
KARTA karta[52]; // KARTA - это структура
};
 
int KolodaKart::giveACard()
{   
if ( getPoints > 20 ) // Тут встает проблема: как узнать какой объект Gambler вызвал эту функцию?
return 0;    // Не знаю как это сделать.
else
return 10;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Gambler
public:
void getCard() // тянем карту
int getPoints() // узнать количество очков у объекта
 
private:
static KolodaKart koloda;
int points;
};
 
void Gambler::getCard()
{  points += koloda.giveACard(); }
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
01.02.2013, 02:02
Цитата Сообщение от eoLithic Посмотреть сообщение
должна узнавать сколько очков у объекта типа Gamber, который вызвал ее.
что то вы путаетесь в показаниях. Как методы одного класса могут быть вызваны объектом другого класса без создания объекта первого? А если объект есть - то предоставьте интерфейс в виде get методов.
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
01.02.2013, 09:36
Цитата Сообщение от eoLithic Посмотреть сообщение
Объект класса Gambler вызывает функцию getCard(). В зависимости от того сколько очков у игрока, функция выдает ему определенное количество очков. Но функция getCard() в своем теле вызывает функцию giveACard() класса KolodaKart и giveACard() должна узнавать сколько очков у объекта типа Gamber, который вызвал ее. В этом и вся проблема.
Это проблема в архитектуре. Класс отвечает за слишком многое, потому и возникают такие дилеммы. Старайтесь, чтобы класс отвечал за как можно более узкую область и при этом был как можно более универсальным.

Пример на коленке:
Три (относительно) универсальных класса для игры в очко.
Card -- карта, знает название ранков и мастей (rank & suit)
Deck -- колода, содержит карты, умеет выдавать случайную карту (drow)
Hand -- "рука" игрока, держит карты, умеет уже считать очки (value).
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
159
#include <cstdlib>
#include <ctime>
#include <string>
#include <iomanip>
#include <iostream>
#include <set>
#include <vector>
#include <stdexcept>
#include <algorithm>
 
class Card {
 public:
  static const std::string RANKS[];
  static const std::string SUITS[];
  static const int NUMBER_OF_CARDS_PER_SUIT = 15;
  Card(int id) : id(id) {}
  Card(int rank, int suit) : id(suit * NUMBER_OF_CARDS_PER_SUIT + rank) {}
  int getId() const { return id; }
  int getRankId() const { return id % NUMBER_OF_CARDS_PER_SUIT; }
  int getSuitId() const { return id / NUMBER_OF_CARDS_PER_SUIT; }
  const std::string &getRankName() const { return RANKS[getRankId()]; }
  const std::string &getSuitName() const { return SUITS[getSuitId()]; }
 private:
  int id;
};
 
const std::string Card::RANKS[] = {"zero", "one",
  "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
  "jack", "queen", "king", "ace"};
const std::string Card::SUITS[] = {"hearts", "diamonds", "clubs", "spades",
  "joker"};
 
std::ostream &operator<<(std::ostream &stream, const Card &card) {
  if (card.getSuitId() < 4) {
    stream << card.getRankName() << " of " << card.getSuitName();
  } else {
    stream << card.getSuitName();
  }
  return stream;
}
 
// íàäî äëÿ ìíîæåñòâà
bool operator<(const Card &a, const Card &b) {
  if (a.getRankId() == b.getRankId())
    return a.getSuitId() < b.getSuitId();
  return a.getRankId() < b.getRankId();
}
 
class Deck {
 public:
  Deck() : cards() {}
  Card drow() {
    if (cards.empty()) {
      throw std::underflow_error("no cards in deck");
    }
    std::set<Card>::iterator randomCardIterator = cards.begin();
    std::advance(randomCardIterator, rand() % cards.size());
    Card randomCard = *randomCardIterator;
    cards.erase(randomCardIterator);
    return randomCard;
  }
  void reset(int startRankId, int endRankId = Card::NUMBER_OF_CARDS_PER_SUIT,
    int numberOfJokers = 0) {
    cards.clear();
    for (int i = 0; i < 4; ++i) {
      for (int j = startRankId; j < endRankId; ++j) {
        cards.insert(Card(j, i));
      }
    }
    for (int i = 0; i < numberOfJokers; ++i) {
      cards.insert(Card(i, 4));
    }
  }
  bool isEmpty() const {
    return cards.empty();
  }
  int getSize() const {
    return cards.size();
  }
  friend std::ostream &operator<<(std::ostream &stream, const Deck &deck) {
    for (std::set<Card>::const_iterator i = deck.cards.begin();
      i != deck.cards.end(); ++i) {
      stream << (*i) << std::endl;
    }
    return stream;
  }
 private:
  std::set<Card> cards;
};
 
// ðóêà äëÿ èãðû â 21
class Hand {
 public:
  Hand() : cards(), value(0) {}
  // äîáàâëåíèå êàðòû â ðóêó ñ ïåðåñ÷åòîì î÷êîâ
  void addCard(const Card &card) {
    cards.insert(card);
    if (card.getRankId() == 13) { // Ace
      value += ((value + 11 > 21) ? 1 : 11);
    } else if (card.getRankId() < 11) { // 0 .. 10
      value += card.getRankId();
    } else { // Jack = 2, Queen = 3, King = 4
      value += card.getRankId() - 9;
    }
  }
  int getValue() const {
    return value;
  }
  void clear() {
    value = 0;
    cards.clear();
  }
 private:
  std::set<Card> cards;
  int value;
};
 
int getNumberOfAliveHands(const std::vector<Hand> &hands) {
  int numberOfPlayers = 0;
  for (int i = 0; i < hands.size(); ++i) {
    if (hands[i].getValue() <= 21) {
      ++numberOfPlayers;
    }
  }
  return numberOfPlayers;
}
 
int main(int argc, char **argv) {
  srand(time(0));
 
  // êîëîäà
  Deck deck;
  // ñáðîñ è çàïîëíåíèå êîëîäû çíà÷åíèÿìè îò 6 äî òóçà
  // ÷åòûðåõ ìàñòåé
  deck.reset(6);
  
  // 4 "ðóêè" èãðîêîâ
  std::vector<Hand> hands(4);
  
  int i = 0;
  do {
    if (hands[i].getValue() < 21) {
      Card card = deck.drow();
      hands[i].addCard(card);
      std::cout << "Player " << i << " got " << card << " and now has " <<
        hands[i].getValue() << " points." << std::endl;
    }
    if (hands[i].getValue() == 21) {
      std::cout << "Player " << i << " wins." << std::endl;
      break;
    } else if (hands[i].getValue() > 21) {
      std::cout << "Player " << i << " has lost." << std::endl;
    }
    i = (i + 1) % hands.size();
  } while (getNumberOfAliveHands(hands) > 1); // óñëîâèå îêîí÷àíèÿ íàäî ëó÷øå ïðîäóìàòü
 
  std::cin.get();
  return 0;
}
0
0 / 0 / 0
Регистрация: 05.01.2013
Сообщений: 32
01.02.2013, 09:45  [ТС]
Спасибо всем за советы. Проблему решил тем, что функция, раздающая очки, начала принимать в качестве параметра нынешнее количество очков у объекта

Однако, пойду улучшать свою архитектуру.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.02.2013, 09:45
Помогаю со студенческими работами здесь

Как динамически создать массив контролов?
Создать один контрол. Set NewLabel = Controls.Add(&quot;VB.Label&quot;, MyName$) With NewLabel .Visible = True .Caption =...

Динамически создать массив и вернуть его из функции
Здравствуйте! Возникла проблема с динамическими массивами... Насколько я знаю, строчка short* c = (short*)malloc(5*sizeof(short)); ...

Как создать массив заданной длины динамически
Есть длина будущего массива. Как его создать? Пробовал через malloc но что не получалось char buff; int i, j, c; for (i = 0;...

Как создать массив динамически созданных TextBox
Как создать массив динамически созданных TextBox, а также вывести TextBox.Text

Динамически создать массив, количество элементов вводится с клавиатуры
Динамически создать массив, количество элементов вводится с клавиатуры. Заполнить мас-сив с помощью генератора случайных величин числами...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru