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

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

Войти
Регистрация
Восстановить пароль
 
 
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
#1

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

01.04.2010, 15:00. Просмотров 988. Ответов 15
Метки нет (Все метки)

Есть класс, к примеру вектора, я максимально упростил его чтоб легче было понять ошибку, вот его реализация:

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

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

Не работает деструктор и ошибка при использовании SSE-команд. - C++
Написал класс матрицы, начал писать деструктор - начало вылазить сообщение об ошибке вида &quot;Expression:...

Обьявление полей класа - C++
Доброго дня! Как скомпилить #include &lt;iostream&gt; class Counter { public: ...

неправильно работает метод класа - C++
подскажите пожалуйста написал часть кода, он ище далек от окончания, но что у меня щас уже не нравильно работает, мой метод класса...

Копирующий конструктор абстрактного класа - C++
Добрый вечер. Сразу к делу. Есть абстрактный класс: class Product abstract { protected: int lipids; string brand; ...

Инициализация статической константы класа - C++
Есть некий класс в котором необходимы статичесие константы Код который ниже, компилятором принимаеться и даже работает. class MyClass{ ...

15
yanyk1n
4330 / 1461 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:06 #2
private:
double * x;
Так вы же объявили как указатель на переменную, а работа с классом осуществляется как с массивом
0
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 15:07  [ТС] #3
А как же тогда правильно очистить память в деструкторе? Или этого делать вообще не нужно в этом случае?
0
yanyk1n
4330 / 1461 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:12 #4
savak, стоит подкорректировать определение класса в public, раз с X вы работаете как с массивом
0
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 15:23  [ТС] #5
Извини, я новичок в ООП, не совсем еще понимаю все эти тонкости! Не покажешь, что конкретно надо исправить?
0
yanyk1n
4330 / 1461 / 152
Регистрация: 12.03.2009
Сообщений: 5,310
01.04.2010, 15:35 #6
Во всех конструкторах надо вот это написать:
C++
1
x = new double[n_elements];
0
savak
2 / 2 / 0
Регистрация: 28.03.2009
Сообщений: 61
01.04.2010, 16:07  [ТС] #7
Ну так во всех конструкторах это и написано!

Добавлено через 29 минут
Помогите разобраться!
0
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,403
01.04.2010, 16:45 #8
Копирующий конструктор и оператор= допиши.
0
pety
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 116
18.06.2015, 20:52 #9
Если не сложно, объясните, что значит
C++
1
typedef class Vector
0
Fulcrum_013
Заблокирован
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
0
hoggy
6717 / 2900 / 497
Регистрация: 15.11.2014
Сообщений: 6,525
Завершенные тесты: 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;
}
1
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
18.06.2015, 22:31 #12
Цитата Сообщение от savak Посмотреть сообщение
a = a.Normalize();
что ты хотел сказать этой строчкой
вот здесь то и выплывает конструктор копирования которого нет
в результате память освобождается дважды
пиши проще
C++
1
a.Normalize();
0
Черный мечник
48 / 49 / 17
Регистрация: 29.12.2012
Сообщений: 425
18.06.2015, 23:02 #13
hoggy, Интереснинько насчет typedef class Vector
0
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;
0
hoggy
6717 / 2900 / 497
Регистрация: 15.11.2014
Сообщений: 6,525
Завершенные тесты: 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;
1
20.06.2015, 20:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.06.2015, 20:38
Привет! Вот еще темы с ответами:

использовать даные класа А в классе Б и В - C++
Нужно использовать даные класа А в классе Б и В...как это реализовать??? Добавлено через 38 минут покажите хотя б на простом...

Доступ к обьекту класа с другого файла - C++
C++ Builder (Embarcadero RAD Studio 10.2) Здравствуйте, создав 2 форму в проекте доступ к ней с 1 формы можно примерно (в зависимости от...

Вызов функции одного класа в другом - C++
Доброго времени суток всем!:) Столкнулся с такой проблемой, не судите строго, только начал изучать ООП и тут возникла трабла... Есть 2...

Клас с полем типа другого класа - C++
Есть клас car с полями и методом заполнения етих полей. Надо написать клас tz в котором есть поле типа сar и пару других полей и метод...


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

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

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