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

Деструктор класа, ошибка - C++

Восстановить пароль Регистрация
 
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 15:00     Деструктор класа, ошибка #1
Есть класс, к примеру вектора, я максимально упростил его чтоб легче было понять ошибку, вот его реализация:

Vector.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
#ifndef _VECTOR_H_
#define _VECTOR_H_
 
#include <iostream>
using namespace std;
 
#include <math.h>
#define PI 3.14159265358979323846264338327950
 
typedef class Vector
{
private:
    double * x;
    int n_elements;
 
public:
    // Конструктор
    Vector();
    Vector(double x1, double y1, double z1);
    Vector(int n_elem, double n = 0);
 
    ~Vector() {delete[] x;}
 
    double & operator() (int i);
    double & operator() (int i) const {return x[i];}
 
    int Count() const;
 
    // Унарные операции над векторами (свойства)
    double Length() const;                      // Возвращает длину вектора
    Vector Normalize() const;                   // Возвращает нормализованный вектор
} Point;
 
#endif
Vector.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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "Vector.h"
 
Vector::Vector()
{
    n_elements = 3;
    x = new double[n_elements];
    for(int i = 0; i < n_elements; i++)
        x[i] = 0;
}
 
// Инициализирующий конструктор
Vector::Vector(double x1, double y1, double z1)
{
    n_elements = 3;
    x = new double[n_elements];
    x[0] = x1, x[1] = y1, x[2] = z1;
}
 
Vector::Vector(int n_elem, double n)
{
    n_elements = n_elem;
    x = new double[n_elements];
    for(int i = 0; i < n_elements; i++)
        x[i] =  n;
}
 
double & Vector::operator() (int i)
{
    return *(x + i);
}
 
int Vector::Count() const
{
    return n_elements;
}
 
// Нахождение длины вектора
double Vector::Length() const
{
    double c = 0;
    for(int i = 0; i < n_elements; i++)
        c += x[i]*x[i];
    return sqrt(c);
}
 
// Нормализация вектора
Vector Vector::Normalize() const
{
    Vector A(n_elements);
    A = (*this);
    for(int i = 0; i < n_elements; i++)
        A.x[i] = A.x[i] / Length();
    return A;
}
main:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "Vector.h"
 
using namespace std;
 
void main(void)
{
    Vector a(1,2,3);
    a = a.Normalize();
}
Проблемы здесь, как я понял в деструкторе класса. При выходе из функции Normalize программа толи зацикливается, то ли что то в этом духе! Помогите, пожалуйста найти ошибку! Пол дня вчера сидел, но ничего не нашел! Вроде деструктор по всем правилам объявлен!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
yanyk1n
 Аватар для yanyk1n
4324 / 1455 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:06     Деструктор класа, ошибка #2
private:
double * x;
Так вы же объявили как указатель на переменную, а работа с классом осуществляется как с массивом
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 15:07  [ТС]     Деструктор класа, ошибка #3
А как же тогда правильно очистить память в деструкторе? Или этого делать вообще не нужно в этом случае?
yanyk1n
 Аватар для yanyk1n
4324 / 1455 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:12     Деструктор класа, ошибка #4
savak, стоит подкорректировать определение класса в public, раз с X вы работаете как с массивом
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 15:23  [ТС]     Деструктор класа, ошибка #5
Извини, я новичок в ООП, не совсем еще понимаю все эти тонкости! Не покажешь, что конкретно надо исправить?
yanyk1n
 Аватар для yanyk1n
4324 / 1455 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:35     Деструктор класа, ошибка #6
Во всех конструкторах надо вот это написать:
C++
1
x = new double[n_elements];
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 16:07  [ТС]     Деструктор класа, ошибка #7
Ну так во всех конструкторах это и написано!

Добавлено через 29 минут
Помогите разобраться!
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
01.04.2010, 16:45     Деструктор класа, ошибка #8
Копирующий конструктор и оператор= допиши.
pety
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 116
18.06.2015, 20:52     Деструктор класа, ошибка #9
Если не сложно, объясните, что значит
C++
1
typedef class Vector
Fulcrum_013
 Аватар для Fulcrum_013
393 / 566 / 60
Регистрация: 14.12.2014
Сообщений: 4,769
Завершенные тесты: 2
18.06.2015, 21:18     Деструктор класа, ошибка #10
Цитата Сообщение от savak Посмотреть сообщение
При выходе из функции Normalize программа толи зацикливается, то ли что то в этом духе!
А какая длина вектора? А то при такой реализации Normalize время на вычисление пропорционально квадрату размера.
C++
1
2
3
4
5
6
7
Vector Vector::Normalize() const
{
   float magnitude= Length();
    for(int i = 0; i < n_elements; i++)
        x[i]/=magnitude; 
    return *this;
}
Добавлено через 5 минут
Да кстати если вектора под 3D делаешь (т.е. размер будет фиксирован и намерен это для чего то серьезного пользовать а не как лабу) то лучше массив x объявить так:
C++
1
2
3
4
5
6
7
8
9
10
11
class Vector
{
private:
    union{
          double Axes[4];
          struct{
                  double x,y,z,w;
           }
    } 
 
    int n_elements
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
18.06.2015, 22:23     Деструктор класа, ошибка #11
Цитата Сообщение от pety Посмотреть сообщение
Если не сложно, объясните, что значит
typedef class Vector
рассмотрим код:

C++
1
2
3
4
typedef class Vector
{
 
} Point;
здесь имя класса - Vector.
но у него есть другое имя (псевдоним) - Point

можно делать так:
C++
1
Vector vec;
можно так:
C++
1
Point p;
это будет создание двух экземпляров одного и того же класса.

Добавлено через 21 минуту
Цитата Сообщение от savak Посмотреть сообщение
Проблемы здесь, как я понял в деструкторе класса.
Нарушение правила "трех": если конструктор аллоцирует память по указателю при помощи new, значит требуются так же конструктор копии, и оператор=

лекарство:

http://rextester.com/PNKOC97940

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
using namespace std;
 
#include <math.h>
#define PI 3.14159265358979323846264338327950
 
typedef class Vector
{
    size_t n_elements;
    double* x;
 
public:
    template<class T> friend
    std::basic_ostream<T>&
        operator<<(::std::basic_ostream<T>& os, const Vector& obj )
        {
            for(size_t n = 0; n< obj.n_elements; ++n)
                os<< obj.x[n]<<", ";
            return os;
        }
    
public:
    Vector();
    Vector(const double x1, const double y1, const double z1);
    Vector(const size_t n_elem, const double n = 0);
    Vector(const Vector& rhs);
    Vector(Vector&& rhs);
 
   ~Vector() {delete[] x;}
 
    const Vector& operator=(const Vector& rhs);
    const Vector& operator=(Vector&& rhs);
    
    double& operator() (const size_t i);
    double& operator() (const size_t i) const {return x[i];}
 
    size_t Count() const;
 
    double Length() const;      
    Vector Normalize() const;   
} Point;
 
Vector::Vector()
    : n_elements(3)
    , x(new double[n_elements])
{
    for(size_t i = 0; i < n_elements; ++i)
        x[i] = 0;
}
 
Vector::Vector(const double x1, const double y1, const double z1)
    : n_elements(3)
    , x(new double[n_elements])
 
{ x[0] = x1; x[1] = y1; x[2] = z1; }
 
Vector::Vector(const size_t n_elem, const double n)
    : n_elements(n_elem)
    , x(new double[n_elements])
 
{
    for(size_t i = 0; i < n_elements; ++i)
        x[i] =  n;
}
 
Vector::Vector(const Vector& rhs)
    :n_elements(rhs.n_elements)
    ,x(new double[n_elements])
{
    for(size_t i = 0; i < n_elements; ++i)
        x[i] =  rhs.x[i];
}
 
Vector::Vector(Vector&& rhs)
    :n_elements(rhs.n_elements)
    ,x(new double[n_elements])
{
    rhs.n_elements = 0;
    rhs.x=nullptr;
}
 
const Vector& Vector::operator=(const Vector& rhs)
{
    delete[] x;
    n_elements = rhs.n_elements;
    x = new double[n_elements];
    
    for(size_t i = 0; i < n_elements; ++i)
        x[i] =  rhs.x[i];
    return *this;
}
 
const Vector& Vector::operator=(Vector&& rhs)
{
    delete[] x;
    n_elements = rhs.n_elements;
    x = rhs.x;
    
    rhs.n_elements = 0;
    rhs.x=nullptr;
    
    return *this;
}
 
 
double& Vector::operator() (const size_t i)
    { return x[i]; }
 
size_t Vector::Count() const
    { return n_elements; }
 
double Vector::Length() const
{
    double c = 0;
    for(size_t i = 0; i < n_elements; ++i)
        c += x[i]*x[i];
    return sqrt(c);
}
 
Vector Vector::Normalize() const
{
    Vector A = *this;
    for(size_t i = 0; i < n_elements; ++i)
        A.x[i] = A.x[i] / Length();
    return A;
}
 
 
int main()
{
    Point a(1,2,3);
    
    std::cout<<"point: "<< a << std::endl;
    
    a.Normalize();
    
    a = a.Normalize();
    
    Point b( Vector(4,5,6) );
    std::cout<<"point: "<< b << std::endl;
}
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,052
18.06.2015, 22:31     Деструктор класа, ошибка #12
Цитата Сообщение от savak Посмотреть сообщение
a = a.Normalize();
что ты хотел сказать этой строчкой
вот здесь то и выплывает конструктор копирования которого нет
в результате память освобождается дважды
пиши проще
C++
1
a.Normalize();
Черный мечник
48 / 49 / 17
Регистрация: 29.12.2012
Сообщений: 417
18.06.2015, 23:02     Деструктор класа, ошибка #13
hoggy, Интереснинько насчет typedef class Vector
pety
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 116
20.06.2015, 20:20     Деструктор класа, ошибка #14
hoggy, хорошо, но чем эта запись отличается от такой
C++
1
2
3
4
5
6
7
8
9
class Vector
{
 
};
 
typedef Vector Point;
 
Vector vec;
Point p;
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
20.06.2015, 20:38     Деструктор класа, ошибка #15
Цитата Сообщение от pety Посмотреть сообщение
hoggy, хорошо, но чем эта запись отличается от такой
принципиально - ничем.

вообще, такая форма записи с тайпдефом - это наследние языка си.

на языке с++, что бы объявить экземпляр класса можно написать просто:
C++
1
some obj;
на языке си:
C
1
struct some obj;
и там, и там, тайпдефы позволяют опускать ключевое слово struct/class

вам нужно быть готовым встретить нечто подобное в чужом старом коде.

но на языке с++ такое не практикуется.

тобишь, хотите сделать тапйдеф, делайте его по человечачьи:
C++
1
2
3
4
5
6
class Vector
{
 
};
 
typedef Vector Point;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.06.2015, 20:44     Деструктор класа, ошибка
Еще ссылки по теме:

C++ Копирующий конструктор абстрактного класа
C++ Почему создается виртуальный деструктор A, а в таблице виртуальных функций лежит деструктор B
Обьявление полей класа C++

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

Или воспользуйтесь поиском по форуму:
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
20.06.2015, 20:44     Деструктор класа, ошибка #16
Те, кто отвечает ТС, посмотрите на дату.
Yandex
Объявления
20.06.2015, 20:44     Деструктор класа, ошибка
Ответ Создать тему
Опции темы

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