С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Маркенштейн
0 / 0 / 1
Регистрация: 22.04.2013
Сообщений: 44
#1

Почему все экземпляры класса в векторе имеют абсолютно одни и те же характеристики? - C++

29.03.2014, 15:50. Просмотров 889. Ответов 24
Метки нет (Все метки)

Доброе время суток!

Суть:
Есть класс, в конструкторе которого некоторые переменные класса задаются рандомно.
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
enum Sex {male, female};
 
class Animal
{
public:
    Animal();
    ~Animal();
    
    int getSpeed();
    int getStrength();
    int getSkill();
    int getIntelligence();
 
    bool full;      //bellyfull
 
    bool searchFood(Environment env);
    bool searchFemale();
    bool seductionFemale();
    void reproduction();
    void nextGeneration(Environment env);
    //Animal natureSelection(Animal *animals[]);
private:
    int age;        //1...10
    Sex sex;        //male, female
    
    int hungry;
    //genome------------------
    int speed;          //1...10 by random
    int strength;       //1...10 by random
    int skill;          //1...10 by random
    int intelligence;   //1...10 by random
    //genome------------------
    Sex randSex();
};
Есть vector с экземплярами этого класса.
C++
1
std::vector <Animal> animals (env.countOfAnimals);
Вопрос:
Почему все экземпляры этого класса в векторе имеют абсолютно одни и те же характеристики, словно клоны?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.03.2014, 15:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему все экземпляры класса в векторе имеют абсолютно одни и те же характеристики? (C++):

Как перебрать все экземпляры класса? - C++
Здравствуйте! Я начинающий программист..... может и не программист вовсе. Но мне необходимо сделать такую задачу. С классами начала...

friend функции не имеют доступа к private элементам класса, почему? - C++
Учусь по Лафоре Р. - Объектно-ориентированное программирование в С++ (Классика Computer Science) - 2004. Выполняю задания на Microsoft...

Как получить доступ к методам класса, который содержится в векторе класса - C++
Пишу дерево с любым количеством наследников. В классе Thread содержится вектор классов Thread. При попытке просмотра первого элемента в...

С помощью метода получить все экземпляры класса-потомка - C#
Прошу прощения за кривизну вопроса, не знаю как спросить у гугла class MyClass { static List&lt;MyClass&gt; myList = new...

Экземпляры класса - PHP ООП
Здравствуйте! Я затупил и не могу понять такую вещь) Вот есть у меня, например, класс CRUD, он занимается манипуляциями с данными из БД....

экземпляры класса - C#
По лабе надо написать консольное приложение, что то вроде базы данных студентов, пишу я и столкнулся с такой проблемой: при добавлении...

24
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
29.03.2014, 17:35 #2
Код весь видеть надо, но сильно подозреваю по строчке:
Цитата Сообщение от Маркенштейн Посмотреть сообщение
std::vector <Animal> animals (env.countOfAnimals);
, что все как один они созданы конструктором по-умолчанию, с едиными свойствами (по-умолчанию)
0
Маркенштейн
0 / 0 / 1
Регистрация: 22.04.2013
Сообщений: 44
29.03.2014, 17:50  [ТС] #3
Вот код конструктора и рандомайзера:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Animal::Animal()
{
    this->age = 1;
    this->sex = randSex();
    this->full = false;
    this->hungry = 0;
    this->speed = randomize(11);
    this->strength = randomize(11);
    this->skill = randomize(11);
    this->intelligence = randomize(11);
}
 
int randomize(int limit)
{
    int res;
    do
    {res = rand() % limit;}
    while(res == 0);
    return res;
}
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
29.03.2014, 20:46 #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
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <time.h>
#include <vector>
 
using namespace std;
enum Sex {male, female};
int randomize(int limit);
 
class Animal
{
public:
    Animal();
    ~Animal(){;}
    
    int getSpeed(){return speed;}
    int getStrength(){return strength;}
    int getSkill(){return skill;}
    int getIntelligence(){return intelligence;}
    bool full;      //bellyfull
    //Animal natureSelection(Animal *animals[]);
private:
    int age;        //1...10
    Sex sex;        //male, female
    
    int hungry;
    //genome------------------
    int speed;          //1...10 by random
    int strength;       //1...10 by random
    int skill;          //1...10 by random
    int intelligence;   //1...10 by random
    //genome------------------
    Sex randSex(){return male;}
};
 
Animal::Animal()
{
    this->age = 1;
    this->sex = randSex();
    this->full = false;
    this->hungry = 0;
    this->speed = randomize(11);
    this->strength = randomize(11);
    this->skill = randomize(11);
    this->intelligence = randomize(11);
}
 
int randomize(int limit)
{
    int res;
    do
    {res = rand() % limit;}
    while(res == 0);
    return res;
}
 
int main ()
{
    const int r=10;
        srand( (unsigned)time( NULL ) );
    vector <Animal> animals (r);
    for (int i=0 ; i<r;++i) cout<<animals[i].getSpeed()<<"   "<<animals[i].getSkill() <<"   "<<animals[i].getStrength() <<"   "<<animals[i].getIntelligence() <<endl;
    system ("Pause");
    return 0;
}
И вот результат:
Почему все экземпляры класса в векторе имеют абсолютно одни и те же характеристики?
0
Маркенштейн
0 / 0 / 1
Регистрация: 22.04.2013
Сообщений: 44
29.03.2014, 22:50  [ТС] #5
Спасибо, но это не то. Я виноват, забыл сказать сразу.
Объем вектора нам заранее неизвестен, он задается переменной env.countOfAnimals, значение которой нам выдает все тот же рандомайзер при создании экземпляра класса Environment env.
А так, как у вас сделано, я и сам могу

Добавлено через 9 минут
Вот тут исходники, чтобы больше не было вопросов
http://dropmefiles.com/FVRNV
Смотрите и пугайтесь. Я пока сделал динамическим массивом, но хотелось бы все-таки перейти на vector
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
30.03.2014, 11:08 #6
Маркенштейн, Так я чего то не понимаю? Я собираю Ваш проект и с динамическим массивом и с вектором, и вот этого
Цитата Сообщение от Маркенштейн Посмотреть сообщение
Почему все экземпляры этого класса в векторе имеют абсолютно одни и те же характеристики, словно клоны?
у меня нет... Характеристики у них у Всех отличаются:
Почему все экземпляры класса в векторе имеют абсолютно одни и те же характеристики?
Другой момент, что стоит добавить заголовочный файл может быть:
C++
1
#include <time.h>
и следующую строчку в int randomize(int limit)
C++
1
srand( (unsigned)time( NULL ) );
1
Маркенштейн
0 / 0 / 1
Регистрация: 22.04.2013
Сообщений: 44
30.03.2014, 17:40  [ТС] #7
Хм, странно. Может быть дело в том, что у меня студия старенькая - 2008, еще и express? Может быть и в рандомайзере, да. Но динамическим массивом все нормально, а вектором - клоны. Странно. Есть какие-нибудь идеи?
А рандомом по системному времени я не пользуюсь во время отладки, так удобнее, имхо
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
30.03.2014, 18:00 #8
Цитата Сообщение от Маркенштейн Посмотреть сообщение
А рандомом по системному времени я не пользуюсь во время отладки
Да я понял, что Вы "бывалый", а не "молодой", но совет уж так для очистки совести... А вот по поводу
Цитата Сообщение от Маркенштейн Посмотреть сообщение
Может быть дело в том, что у меня студия старенькая - 2008,
простите ничего сказать не могу
0
zss
Модератор
Эксперт С++
6579 / 6141 / 2023
Регистрация: 18.12.2011
Сообщений: 16,004
Завершенные тесты: 1
30.03.2014, 18:52 #9
При трассировке программы можно увидеть, что при выполнении строки
C++
1
 vector <Animal> animals (r);
конструктор Animal::Animal()
вызывается только один раз.
А остальные члены похоже просто копируются.
У меня тоже VS 2008
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
30.03.2014, 18:59 #10
zss, А в VS2012 тогда изменили это выходит?
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
30.03.2014, 19:10 #11
Цитата Сообщение от zss Посмотреть сообщение
вызывается только один раз.
И даже для такого кода будет 1 раз?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
 
struct S
{
    S() { std::cout << i++ << std::endl; }
    static int i;
};
 
int S::i = 0;
 
int main() {
    
    std::vector<S> s(10);
    return 0;
}
http://ideone.com/GU62Ej
0
zss
Модератор
Эксперт С++
6579 / 6141 / 2023
Регистрация: 18.12.2011
Сообщений: 16,004
Завершенные тесты: 1
30.03.2014, 19:15 #12
Цитата Сообщение от mustimur Посмотреть сообщение
А в VS2012 тогда изменили это выходит
Действительно. Попробовал в VS2010.
Конструктор вызывается многократно.
И числа соответственно разные.

Добавлено через 2 минуты
Цитата Сообщение от Tulosba Посмотреть сообщение
И даже для такого кода будет 1 раз?
Попробовал В VS 2008 - ОДИН раз!
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
30.03.2014, 21:26 #13
Всё дело в используемой версии стандарта.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
 
struct S
{
    S() { std::cout << i++ << std::endl; }
    static int i;
// private:
    S( const S& ) { std::cout << "copy" << std::endl; }
};
 
int S::i = 0;
 
int main() {
    
    std::vector<S> s(10);
    return 0;
}
В варианте C++03 конструктор вектора с целым аргументом осуществляет создание объекта конструктором объекта по умолчанию и потом копирует его заданное кол-во раз.
http://coliru.stacked-crooked.com/a/f7a27b9202d52c59

Если копирующий конструктор сделать недоступным, то будет ошибка компиляции.
http://coliru.stacked-crooked.com/a/2c8d613ac75764bf

В варианте C++11 копирующий конструктор не требуется, т.к. каждый раз вызывается конструктор объекта по умолчанию.
http://coliru.stacked-crooked.com/a/503e0f6b090375c4

Добавлено через 15 минут
Различие поведения вытекает из-за того, что в C++03 конструктор заполнения имеет только одну сигнатуру:
C++
1
explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());
И внутри осуществляется копирование n раз объекта val, который по умолчанию создается конструктором объекта по умолчанию (малость тавтологично звучит )
В то время как в C++11 уже существует два варианта:
C++
1
2
explicit vector (size_type n);
         vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
Первый - создает n объектов путем вызова n раз конструктора по умолчанию.
Второй - копирует объект val n раз, но в этот раз параметр уже не имеет значения по умолчанию и должен передаваться явно.
3
Маркенштейн
0 / 0 / 1
Регистрация: 22.04.2013
Сообщений: 44
31.03.2014, 10:51  [ТС] #14
Цитата Сообщение от mustimur Посмотреть сообщение
zss, А в VS2012 тогда изменили это выходит?
Выходит, что да
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
31.03.2014, 14:27 #15
Маркенштейн, переход на C++11

Добавлено через 3 часа 17 минут
Tulosba, А вот теперь любопытно стало, по идеи VS2010 на C++03 должен быть, а тем не менее
Цитата Сообщение от zss Посмотреть сообщение
Попробовал в VS2010.
Конструктор вызывается многократно.
Добавлено через 3 минуты

Не по теме:

Или это из серии "Пути Microsoft неисповедимы?"

0
31.03.2014, 14:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2014, 14:27
Привет! Вот еще темы с ответами:

Разные экземпляры класса ? - C++
Есть класс Visitor и в нем объявленна функция void visitor:: enterToPark(jurassicPark jp){ //Trying to enter to park at every...

Указатель на экземпляры класса - C#
Доброе время суток господа профи. У меня вопрос допустим что есть класс A и в программе есть несколько его экземпляров таких классов, так...

.NET 4.x Потоки и экземпляры класса - C#
Добрый день. Возник такой вопрос, сейчас пишу игру. Есть класс Game, метод NewGame, который начинает новую игру Вопрос в следующем...

ConcurrentMap экземпляры класса клонируются - Java
Добрый день! В ConcurrentMap почему-то клонируются экземпляры классов, несмотря на то, что объявляю новые. Тестировал со String и Integer...


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

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

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