Форум программистов, компьютерный форум CyberForum.ru

Ошибка в конструкторе класса - C++

Восстановить пароль Регистрация
 
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 37
30.04.2014, 14:35     Ошибка в конструкторе класса #1
Всем доброго времени суток!
Есть простая задачка: Написать реализацию класса и короткую программку, использующую все функции-члены.

Есть объявление класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef COW_H
#define COW_H
 
class Cow
{
private:
    char name[20];
    char *hobby;
    double weight;
public:
    Cow();
    Cow(const char * nm, const char * ho, double wt);
    Cow(const Cow &);
    ~Cow();
    Cow & operator=(const Cow &);
    void ShowCow() const;
};
 
 
#endif
Реализация:
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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "Cow.h"
 
using std::cout;
using std::endl;
 
Cow::Cow()
 
{
    char name[20] = {"Burenka"};
    hobby = "eating grass";                                      
    weight = 255.5;
    
    //для отладки
    cout<<"Cow() :"<<'('<<name<<','<<hobby<<','<<weight<<')'<<endl;  
 
}
 
Cow::Cow(const char * nm, const char * ho, double wt)
{
    strcpy(name, nm);
    
    hobby = new char[strlen(ho)+1];                            
    strcpy(hobby, ho);
    
        weight = wt;
    
    //для отладки
    cout<<"Cow() :"<<'('<<name<<','<<hobby<<','<<weight<<')'<<endl;
}
 
Cow::Cow(const Cow &other)
{
    
    strcpy(name, other.name); 
        
    hobby = new char[strlen(other.hobby)+1];         
    strcpy(hobby, other.hobby);
        
    weight = other.weight;
    
    //для отладки
    cout<<"Cow() :"<<'('<<name<<','<<hobby<<','<<weight<<')'<<endl;
 
}
 
Cow::~Cow()
{
    //delete[] hobby;
}
ну и вот собственно тестирую, как работают конструкторы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "Cow.h"
 
 
 
int main()
{
    Cow a;                                                //ok
    Cow b("Marusya","Eat",200.1);             //ok
    Cow q("Zinaida","gives milk",300);       //ok
    Cow c=q;                                            //ok
        Cow c=a;                                            //мусор в name
 
}
Так вот, так: Cow c=q; конструктор копирования работает, все ок, а так: Cow c=a; в name попадает какой-то мусор, то есть в том случае, когда я копирую, объект созданный базовым конструктором. Я так думаю, что проблема, где-то в неправильном определении name в конструкторе по-умолчанию.. Но не могу понять что я делаю не так...
Ну и вот.. еще один момент, который я пока не могу понять, почему когда я добавляю delete[] hobby; в деструктор, программа виснет.. Вроде все правильно делаю, освобождаю память, выделенную в конструкторе.. В общем, буду признателен, за указание на ошибки, может еще, что делаю не совсем так. Заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2014, 14:35     Ошибка в конструкторе класса
Посмотрите здесь:

C++ Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса?
C++ Два динамических массива в конструкторе класса
C++ Инициализация перемнных класса в конструкторе
C++ Добавление в вектор объекта класса в конструкторе
C++ Ошибка в конструкторе копирования класса
Массив объектов в конструкторе другого класса C++
C++ Ошибка в объявлении класса (в конструкторе)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.04.2014, 15:11     Ошибка в конструкторе класса #2
Цитата Сообщение от d01 Посмотреть сообщение
Реализация:
Реализация присваивания где?

Добавлено через 51 секунду
Цитата Сообщение от d01 Посмотреть сообщение
C++
1
2
Cow c=q;//ok
Cow c=a;
Это компилируется?
Ilot
Модератор
Эксперт С++
1778 / 1153 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
30.04.2014, 15:17     Ошибка в конструкторе класса #3
C++
1
2
3
4
Cow::Cow()
 
{
    char name[20] = {"Burenka"};
Вот здесь объявляется переменная скрывающая поле класса и как следствие в name будет храниться мусор.

Добавлено через 2 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Это компилируется?
У автора:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Cow::Cow(const Cow &other)
{
    
    strcpy(name, other.name); 
        
    hobby = new char[strlen(other.hobby)+1];         
    strcpy(hobby, other.hobby);
        
    weight = other.weight;
    
    //для отладки
    cout<<"Cow() :"<<'('<<name<<','<<hobby<<','<<weight<<')'<<endl;
 
}


Добавлено через 1 минуту
Цитата Сообщение от d01 Посмотреть сообщение
Ну и вот.. еще один момент, который я пока не могу понять, почему когда я добавляю delete[] hobby; в деструктор, программа виснет.. Вроде все правильно делаю, освобождаю память, выделенную в конструкторе.. В общем, буду признателен, за указание на ошибки, может еще, что делаю не совсем так. Заранее спасибо.
Проблема скорее всего в том, что вы не выделяете память динамически в конструкторе по умолчанию.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.04.2014, 15:17     Ошибка в конструкторе класса #4
Цитата Сообщение от Ilot Посмотреть сообщение
У автора:
Что у автора? Я спросил про main(), где объявляются две переменные с одинаковыми именами.
Ilot
30.04.2014, 15:20
  #5

Не по теме:

Цитата Сообщение от alsav22 Посмотреть сообщение
Что у автора? Я спросил про main(), где объявляются две переменные с одинаковыми именами.
Пардон, виноват.

d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 37
30.04.2014, 15:48  [ТС]     Ошибка в конструкторе класса #6
alsav22, А нет нет, это я прост незакоментировал, это для наглядности, что копирование объекта, созданнного параметрическим конструктором, срабатывает окей, а объекта, созданного конструктором по умолчанию, в name мусор..

Добавлено через 2 минуты
Ilot, А будьте добры поподробнее, как правильно мне тогда написать контсруктор по умолчанию? А конструктор копирования правильно реализован?
Ilot
Модератор
Эксперт С++
1778 / 1153 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
30.04.2014, 15:57     Ошибка в конструкторе класса #7
Попробуйте. Не проверял.
C++
1
2
3
4
5
6
7
8
9
10
Cow::Cow() {
    strcpy(name, "");
    char temp[] = "eating grass";
    hobby = new char[strlen(temp) + 1];
    strcpy(hobby, temp);                                      
    weight = 255.5;
    //для отладки
    cout<<"Cow() :"<<'('<<name<<','<<hobby<<','<<weight<<')'<<endl;  
 
}
Если мне память не изменяет еще необходимо при использованиии ф-и strcpy добавлять нулевой символ... или я не прав?
Цитата Сообщение от d01 Посмотреть сообщение
А конструктор копирования правильно реализован?
На вскидку, да.
Kuzia domovenok
 Аватар для Kuzia domovenok
1886 / 1741 / 117
Регистрация: 25.03.2012
Сообщений: 5,910
Записей в блоге: 1
30.04.2014, 17:38     Ошибка в конструкторе класса #8
деструктор неправильно реализован.

Добавлено через 5 минут
в деструкторе надо вызывать delete[] hobby;
Но в текущей реализации delete будет приводить к падению! Потому что в текущей реализации вызов delete приведёт к ошибке, если объект был создан конструктором по-умолчанию как
C++
1
  hobby = "eating grass";
надо заменить на
C++
1
2
 hobby = new char[strlen(temp) + 1];
    strcpy(hobby,  "eating grass");
собственно это уже успел написать Ilot!

Добавлено через 1 час 31 минуту
hobby = new char[strlen("eating grass") + 1];
strcpy(hobby, "eating grass");
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 37
30.04.2014, 17:40  [ТС]     Ошибка в конструкторе класса #9
Ilot, Да, так все окей, работает, только вот не понятно остается, по сути strcpy копирует посимвольно, и создает массив чаров, но ведь, так мы тоже создаем и инициализирем массив - char name[20] = {"Burenka"}; В чем разница?
Kuzia domovenok, Да это я тоже понял теперь, то есть если в деструкторе присутствует освобождение памяти, то должно производиться одинаковое выделение, во всех конструкторах, т.к деструктор общий для всех конструкторов.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.04.2014, 17:51     Ошибка в конструкторе класса #10
Цитата Сообщение от d01 Посмотреть сообщение
но ведь, так мы тоже создаем и инициализирем массив - char name[20] = {"Burenka"}; В чем разница?
Локальный массив, который создаётся в конструкторе, после выхода из конструктора его уже нет.
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 37
03.05.2014, 14:55  [ТС]     Ошибка в конструкторе класса #11
alsav22, ну тогда если в конструкторе этот массив сделать static, то по идее он должен сохраняться до окончания работы программы, а все равно мусор.. или я все-таки, что-то не так понимаю.. извините за дотошность, но хочется окончательно разобраться с этим вопросом..
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.05.2014, 15:08     Ошибка в конструкторе класса #12
Ilot уже написал об этом:
Цитата Сообщение от Ilot Посмотреть сообщение
Вот здесь объявляется переменная скрывающая поле класса и как следствие в name будет храниться мусор.
Тот массив, который объявляете в конструкторе, не имеет никакого отношения к полю name класса. В конструкторе нужно не объявлять массив, а инициализировать name:
C++
1
strcpy(name, "Burenka");
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2014, 16:08     Ошибка в конструкторе класса
Еще ссылки по теме:

C++ Полиморфизм в конструкторе класса
C++ С++, delete в деструкторе класса не видит переменные, создаваемые new в конструкторе класса
Что значит const в конструкторе класса? C++
Указатель на this в конструкторе класса C++
Объяснить синтаксис в конструкторе класса C++

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

Или воспользуйтесь поиском по форуму:
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 37
03.05.2014, 16:08  [ТС]     Ошибка в конструкторе класса #13
alsav22, ааа все теперь я понял, я получается, создавал дополнительную переменную, внутри блока, спасибо большое
Yandex
Объявления
03.05.2014, 16:08     Ошибка в конструкторе класса
Ответ Создать тему
Опции темы

Текущее время: 09:04. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru