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

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

Войти
Регистрация
Восстановить пароль
 
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 38
#1

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

30.04.2014, 14:35. Просмотров 477. Ответов 12
Метки нет (Все метки)

Всем доброго времени суток!
Есть простая задачка: Написать реализацию класса и короткую программку, использующую все функции-члены.

Есть объявление класса:
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; в деструктор, программа виснет.. Вроде все правильно делаю, освобождаю память, выделенную в конструкторе.. В общем, буду признателен, за указание на ошибки, может еще, что делаю не совсем так. Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2014, 14:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибка в конструкторе класса (C++):

Ошибка при работе с объектом класса в конструкторе другого класса - C++
Имеется данный код: https://github.com/ubelian/glgame/tree/master/glgame В файле Food.cpp в конструкторе класса Food::Food() на 19...

Ошибка в конструкторе копирования класса - C++
Хотя и делал по образцу, но почему то лезет ошибка записи за пределы динамического массива, хотя и переменные копируются верно (отладчик...

Ошибка в объявлении класса (в конструкторе) - C++
Я не могу разобраться с классами и конструкторами, в строчке Progect();// {numb=0; sum=0; date=;} всегда высвечивает ошибку,...

Ошибка в конструкторе класса динамических строк - C++
Необходимо создать класс динамических строк с конструктором копирования, оператором присваивания, операторами сравнения, операторами...

С++, delete в деструкторе класса не видит переменные, создаваемые new в конструкторе класса - C++
#include &quot;stdafx.h&quot; #include &quot;iostream&quot; #include &quot;math.h&quot; using namespace std; class fun { double t = 0, x = 0, y = 0, z =...

Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса? - C++
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень...

12
alsav22
5428 / 4823 / 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;
Это компилируется?
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 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; в деструктор, программа виснет.. Вроде все правильно делаю, освобождаю память, выделенную в конструкторе.. В общем, буду признателен, за указание на ошибки, может еще, что делаю не совсем так. Заранее спасибо.
Проблема скорее всего в том, что вы не выделяете память динамически в конструкторе по умолчанию.
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.04.2014, 15:17 #4
Цитата Сообщение от Ilot Посмотреть сообщение
У автора:
Что у автора? Я спросил про main(), где объявляются две переменные с одинаковыми именами.
0
Ilot
30.04.2014, 15:20
  #5

Не по теме:

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

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

Добавлено через 2 минуты
Ilot, А будьте добры поподробнее, как правильно мне тогда написать контсруктор по умолчанию? А конструктор копирования правильно реализован?
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 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 Посмотреть сообщение
А конструктор копирования правильно реализован?
На вскидку, да.
1
Kuzia domovenok
2061 / 1906 / 176
Регистрация: 25.03.2012
Сообщений: 6,567
Записей в блоге: 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");
1
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 38
30.04.2014, 17:40  [ТС] #9
Ilot, Да, так все окей, работает, только вот не понятно остается, по сути strcpy копирует посимвольно, и создает массив чаров, но ведь, так мы тоже создаем и инициализирем массив - char name[20] = {"Burenka"}; В чем разница?
Kuzia domovenok, Да это я тоже понял теперь, то есть если в деструкторе присутствует освобождение памяти, то должно производиться одинаковое выделение, во всех конструкторах, т.к деструктор общий для всех конструкторов.
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.04.2014, 17:51 #10
Цитата Сообщение от d01 Посмотреть сообщение
но ведь, так мы тоже создаем и инициализирем массив - char name[20] = {"Burenka"}; В чем разница?
Локальный массив, который создаётся в конструкторе, после выхода из конструктора его уже нет.
0
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 38
03.05.2014, 14:55  [ТС] #11
alsav22, ну тогда если в конструкторе этот массив сделать static, то по идее он должен сохраняться до окончания работы программы, а все равно мусор.. или я все-таки, что-то не так понимаю.. извините за дотошность, но хочется окончательно разобраться с этим вопросом..
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.05.2014, 15:08 #12
Ilot уже написал об этом:
Цитата Сообщение от Ilot Посмотреть сообщение
Вот здесь объявляется переменная скрывающая поле класса и как следствие в name будет храниться мусор.
Тот массив, который объявляете в конструкторе, не имеет никакого отношения к полю name класса. В конструкторе нужно не объявлять массив, а инициализировать name:
C++
1
strcpy(name, "Burenka");
1
d01
2 / 2 / 1
Регистрация: 10.01.2014
Сообщений: 38
03.05.2014, 16:08  [ТС] #13
alsav22, ааа все теперь я понял, я получается, создавал дополнительную переменную, внутри блока, спасибо большое
0
03.05.2014, 16:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2014, 16:08
Привет! Вот еще темы с ответами:

Инициализация объектов класса в конструкторе другого класса - C++
У меня есть класс Subscriber,в котором есть несколько объектов другого класса Date,мне нужно,чтобы при создании Subscriber объекты класса...

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! - C++
Друзья! Почему так? #include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace std; //Вот главный класс class A{ ...

Исключение в конструкторе класса - C++
Всем здравствуйте! Что будет с классом, если в его конструкторе вылетело и не перехватилось исключение. Например: ...

Указатель на this в конструкторе класса - C++
Добрый день! Есть некий синтетический пример: #include &lt;iostream&gt; #include &lt;memory&gt; class B; class A


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

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

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