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

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

11.02.2016, 22:49. Просмотров 989. Ответов 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)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2016, 22:49
Ответы с готовыми решениями:

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

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

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

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

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

5
Байт
Эксперт C
21883 / 13647 / 2878
Регистрация: 24.12.2010
Сообщений: 29,042
12.02.2016, 00:09 2
parsecer, Такого рода вопросы решаются так. Убирается все, явно к делу не относящееся. Проверяешь - осталась ли ошибка. Если осталась - убираешь еще что-нибудь. И так до пропадания ошибки. Тогда возвращаешься к предыдущей версии (ошибочной). Значит ошибка в различиях между этими версиями. Возможно, по этой методе ты и сам ее найдешь. Не найдешь - иди сюда. Тут народ отзывчивый, попробует помочь.
Но читать твои простыни кода, где дело всего лишь в маленькой закорючке - любителей немного.
ЗЫ. То, что я написал выше называется "локализация ошибки"
4
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7667 / 3812 / 522
Регистрация: 04.12.2011
Сообщений: 11,042
Записей в блоге: 7
12.02.2016, 00:13 3
Лучший ответ Сообщение было отмечено parsecer как решение

Решение

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

Цитата Сообщение от Байт Посмотреть сообщение
Убирается все, явно к делу не относящееся.
Вот-вот.
2
8-BITOV
542 / 485 / 104
Регистрация: 05.05.2014
Сообщений: 1,110
12.02.2016, 00:21 4
Байт, IGPIGP, Если два уважаемых человека пришли к практически одинаковому выводу - значит он - верен!
Я тоже присоединяюсь к вашему мнению, хотя ничего нового сказать не могу.
Итого: принято единогласно!
3
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
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
Answers
Эксперт
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); почему там пишется struct если должно...

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

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


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

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

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