Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
parsecer
3 / 3 / 2
Регистрация: 19.07.2015
Сообщений: 74
1

При создании экземпляра класса, создается 2 экземпляра вместо 1

11.02.2016, 22:49. Просмотров 837. Ответов 5
Метки нет (Все метки)

Подсчет экземпляров ведется с помощью статического члена num_dogs, который во всех трех конструкторах (1. по умолчанию, 2. со всеми переменными, 3. копирования) увеличивается на 1. В единственном деструкторе (вызывается только 1 раз, когда выполнение программы выходит за блок main) num_dogs уменьшается на 1.

dog.h
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
class Dog
{
private:
    int m_loyalty;
    int m_size;
 
    Owner & m_owner;
    int m_status;
    int m_sex;
    int m_price;
 
public:
    static Owner  & m_breeder;
    static int num_dogs;
    std::vector<Dog> * m_market;
    std::string m_name;
    friend class Owner;
    friend class Market;
    std::string m_color;
// 1 конструктор
    Dog();
    ~Dog();
//2 конструктор
    Dog(std::string name, int size, int status, int loyalty, int sex, int price, std::vector<Dog> * market, Owner & owner);
    void acquire(std::string n, int v, int s, int l, int g, Owner o);
    void get_owner(Owner owner_name);
    void break_out();
    void show_data() const;
    int lucky_numbers();
    Dog operator+(Dog & a);
    void loyal_decrease();
    friend void play(Dog &a, int m);
    friend std::ostream & operator<<(std::ostream &os, const Dog &a);
    int market_push(std::vector<Dog> & m);
    int market_pop(std::vector<Dog> &m);
//3 конструктор
    Dog(const Dog &); //конструктор копирования
    Dog operator=(const Dog & a); //оператор присваивания
    void dog_calculator();
 
};
dog_methods.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
//конструктор копирования
Dog::Dog(const Dog & a) : m_owner(a.m_owner) //не возвращает ничего, т.к. конструктор
{
    m_loyalty=a.m_loyalty;
    m_size=a.m_size;
    m_status=a.m_status;
    m_sex=a.m_sex;
    m_price=a.m_price;
    m_market=a.m_market; //market один для всех собак;
    m_name=a.m_name;
    num_dogs++;
    dog_calculator();
 
    std::cout<<"Dog(const Dog &)"<<std::endl;
}
 
 Dog::Dog(std::string name, int size, int status, int loyalty, int sex, int price, std::vector<Dog> * market, Owner & owner) : m_owner(owner)
{
    m_name=name;
    m_size=size;
    m_status=status;
    m_loyalty=loyalty;
    m_sex=sex;
    m_price=price;
    m_market=market; //pointer to the market
    m_market->push_back(*this);
    //break_out();
    num_dogs++;
    dog_calculator();
    std::cout<<"BIG CONSTRUCTOR"<<std::endl;
}
dog_calculator() просто отображает значение статического члена num_dogs, который изначально равен 0.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Dog::dog_calculator()
{
    static char abs[3];
    if (num_dogs==1)
    {
        abs[0]='s';
        abs[1]='t';
    }
    else if (num_dogs==2)
    {
      abs[0]='n';
      abs[1]='d';
    }
    else
    {
        abs[0]='t';
        abs[1]='h';
    }
    std::cout<<"The "<<num_dogs<<abs<<" dog '"<<m_name<<"' made"<<std::endl;
}
В main создается 1 экземпляр Dog:

main.cpp
C++
1
2
 Dog Jack("Jack",4, 1, 2, 1, 45, &market, worker);
 cout<<endl<<"total dogs: "<<Dog::num_dogs;
Что дает такой вывод:

C++
1
2
3
4
5
6
7
The 1st dog 'Jack' made //это, похоже, используется
(Dog(const Dog &)// конструктор копирования
The 2nd dog 'Jack' made //тут используется
BIG CONSTRUCTOR//Dog::Dog(std::string name, int size, int status, int loyalty, int sex, int price, std::vector<Dog> * market, Owner & owner) 
total dogs: 2 //это уже main
destroyed //это вызывается деструктор 2 раза при выходе из main
destroed
Как и почему это происходит? И как нужно изменить код, чтобы велся правильный подсчет?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2016, 22:49
Ответы с готовыми решениями:

Ошибка при создании экземпляра класса
На скринах показано, где ошибка Вот код: #include &lt;iostream&gt;...

Размер массива при создании экземпляра класса
Нет возможности использовать динамически выделяемую память под массив....

Создание нового экземпляра дочернего класса из экземпляра базового
Всем привет! Извиняюсь, если вопрос глупый, но что-то не смог найти конкретный...

Сложение экземпляра базового класса и экземпляра наследника
Добрый вечер! Моя задача - сложить экземпляр базового класса и наследника....

Ошибка в создании экземпляра класса
Начал изучать шаблоны , и не могу переделать , подскажите что не так . ...

5
Байт
Эксперт C
18925 / 12143 / 2533
Регистрация: 24.12.2010
Сообщений: 24,721
12.02.2016, 00:09 2
parsecer, Такого рода вопросы решаются так. Убирается все, явно к делу не относящееся. Проверяешь - осталась ли ошибка. Если осталась - убираешь еще что-нибудь. И так до пропадания ошибки. Тогда возвращаешься к предыдущей версии (ошибочной). Значит ошибка в различиях между этими версиями. Возможно, по этой методе ты и сам ее найдешь. Не найдешь - иди сюда. Тут народ отзывчивый, попробует помочь.
Но читать твои простыни кода, где дело всего лишь в маленькой закорючке - любителей немного.
ЗЫ. То, что я написал выше называется "локализация ошибки"
4
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7078 / 3382 / 458
Регистрация: 04.12.2011
Сообщений: 9,404
Записей в блоге: 5
12.02.2016, 00:13 3
Лучший ответ Сообщение было отмечено parsecer как решение

Решение

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

Цитата Сообщение от Байт Посмотреть сообщение
Убирается все, явно к делу не относящееся.
Вот-вот.
2
8-BITOV
541 / 484 / 104
Регистрация: 05.05.2014
Сообщений: 1,108
12.02.2016, 00:21 4
Байт, IGPIGP, Если два уважаемых человека пришли к практически одинаковому выводу - значит он - верен!
Я тоже присоединяюсь к вашему мнению, хотя ничего нового сказать не могу.
Итого: принято единогласно!
3
nd2
2835 / 2403 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
12.02.2016, 01:52 5
Цитата Сообщение от parsecer Посмотреть сообщение
Как и почему это происходит?
Что, собственно, непонятно? По выводу видно, что конструктор копий работает:
Цитата Сообщение от parsecer Посмотреть сообщение
m_market->push_back(*this);
Цитата Сообщение от parsecer Посмотреть сообщение
И как нужно изменить код, чтобы велся правильный подсчет?
Если нужно исключить подсчёт копий, то убери этот подсчёт из конструктора копирования.
1
parsecer
3 / 3 / 2
Регистрация: 19.07.2015
Сообщений: 74
12.02.2016, 17:35  [ТС] 6
Всем спасибо за ответы, дело было в векторе, создавал копии объектов класса.
0
12.02.2016, 17:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.02.2016, 17:35

Ключевое слово struct при создании экземпляра sockaddr_in
struct sockaddr_in my_addr; sizeof (struct sockaddr_in); почему там пишется...

Удаление экземпляра класса в функции самого класса (Ошибка при отладке)
Допустим, у нас есть класс Buffer, который хранит в себе указатель на класс...

Ошибка при добавление экземпляра класса
Добавляю один товар, все хорошо. При повторном добавлении название и вид...


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

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

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