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

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

Войти
Регистрация
Восстановить пароль
 
Вадим Ром
0 / 0 / 1
Регистрация: 11.07.2014
Сообщений: 8
#1

Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. - C++

11.07.2014, 15:36. Просмотров 300. Ответов 11
Метки нет (Все метки)

Подскажите пожалуйста! Написал класс матриц с перегруженными операторами
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
142
143
144
145
146
147
148
149
150
151
152
153
class Matrix3d{
public:
  double** matrix;
  Matrix3d();
  Matrix3d(double m11,double m12,double m13,double m21,double m22,double m23,double m31,double m32,double m33);
  ~Matrix3d();
  Matrix3d* Inverse();
  double determinant();
  double getvalue(int i,int j);
  void setvalue(int i,int j, double value);
  Matrix3d& operator=(const Matrix3d& matr);
  Vector3d operator*(const Vector3d& v);
  Matrix3d operator+(const Matrix3d& m);
  Matrix3d& operator+=(const Matrix3d& matr);
  Matrix3d& operator-=(const Matrix3d& matr);
  static Matrix3d* createBasisByOneVector(const Vector3d& v);
};
 
#include "math.h"
#include "stdio.h"
 
#include "matrix3d.h"
#include "vector3d.h"
#include "constants.h"
 
Matrix3d::Matrix3d(){
  int i,j;
  matrix=new double* [3];
  for(i=0;i<3;++i){
    matrix[i]=new double [3];
    for (j=0;j<3;++j){
      if (i==j){
        matrix[i][j]=1;
      }else{
        matrix[i][j]=0;
      }
    }
  }
}
 
Matrix3d::  Matrix3d(double m11,double m12,double m13,double m21,double m22,double m23,double m31,double m32,double m33){
    matrix=new double* [3];
    for(int i=0;i<3;++i){
        matrix[i]=new double [3];
    }
    matrix[0][0] = m11;
    matrix[0][1] = m12;
    matrix[0][2] = m13;
    matrix[1][0] = m21;
    matrix[1][1] = m22;
    matrix[1][2] = m23;
    matrix[2][0] = m31;
    matrix[2][1] = m32;
    matrix[2][2] = m33;
}
 
Matrix3d::~Matrix3d(){
  int i;
  for(i=0;i<3;++i){
    delete[] matrix[i];
  }
  delete[] matrix;
}
Matrix3d* Matrix3d::Inverse(){
  Matrix3d* inv = new Matrix3d();
  double det;
  det=matrix[0][0]*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1])-matrix[0][1]*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0])+matrix[0][2]*(matrix[1][0]*matrix[2][1]-matrix[1][1]*matrix[2][0]);
  if (fabs(det) > epsilon){
    inv->matrix[0][0]=(1/det)*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1]);
    inv->matrix[0][1]=-(1/det)*(matrix[0][1]*matrix[2][2]-matrix[0][2]*matrix[2][1]);
    inv->matrix[0][2]=(1/det)*(matrix[0][1]*matrix[1][2]-matrix[0][2]*matrix[1][1]);
    inv->matrix[1][0]=-(1/det)*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0]);
    inv->matrix[1][1]=(1/det)*(matrix[0][0]*matrix[2][2]-matrix[0][2]*matrix[2][0]);
    inv->matrix[1][2]=-(1/det)*(matrix[0][0]*matrix[1][2]-matrix[1][0]*matrix[0][2]);
    inv->matrix[2][0]=(1/det)*(matrix[1][0]*matrix[2][1]-matrix[1][1]*matrix[2][0]);
    inv->matrix[2][1]=-(1/det)*(matrix[0][0]*matrix[2][1]-matrix[0][1]*matrix[2][0]);
    inv->matrix[2][2]=(1/det)*(matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1]);
  } else {
      printf("determinant = 0\n");
  }
  return inv;
}
double Matrix3d::determinant(){
  double temp;
  temp=matrix[0][0]*(matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1])-matrix[0][1]*(matrix[1][0]*matrix[2][2]-matrix[1][2]*matrix[2][0])+matrix[0][2]*(matrix[0][1]*matrix[2][1]-matrix[1][1]*matrix[0][2]);
  return temp;
}
double Matrix3d::getvalue(int i,int j){
  return matrix[i][j];
}
void Matrix3d::setvalue(int i,int j, double value){
  matrix[i][j]=value;
}
Matrix3d& Matrix3d::operator=(const Matrix3d& matr){
  int i;
  int j;
  for(i=0;i<3;++i){
    for(j=0;j<3;++j){
        matrix[i][j]=matr.matrix[i][j];
    }
  }
  return *this;
}
 
Vector3d Matrix3d::operator*(const Vector3d& v){
    double x = matrix[0][0]*v.x + matrix[0][1]*v.y + matrix[0][2]*v.z;
    double y = matrix[1][0]*v.x + matrix[1][1]*v.y + matrix[1][2]*v.z;
    double z = matrix[2][0]*v.x + matrix[2][1]*v.y + matrix[2][2]*v.z;
    return Vector3d(x,y,z);
}
 
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            newMatrix.matrix[i][j]=matr.matrix[i][j] + matrix[i][j];
        }
    }
    return newMatrix;
}
 
Matrix3d& Matrix3d::operator+=(const Matrix3d& matr){
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            matrix[i][j] = matr.matrix[i][j] + matrix[i][j];
        }
    }
    return *this;
}
 
Matrix3d& Matrix3d::operator-=(const Matrix3d& matr){
    int i;
    int j;
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            matrix[i][j] = matrix[i][j] - matr.matrix[i][j];
        }
    }
    return *this;
}
 
Matrix3d* Matrix3d::createBasisByOneVector(const Vector3d& v){
    if ((v.z*v.z + v.y*v.y + v.x*v.x) < epsilon){
        return new Matrix3d(1,0,0,0,1,0,0,0,1);
    }
    double theta = acos(v.z/sqrt(v.z*v.z + v.y*v.y + v.x*v.x));
    double phi = atan2(v.y,v.x);
    return new Matrix3d(sin(phi),cos(theta)*cos(phi),sin(theta)*cos(phi),-cos(phi),cos(theta)*sin(phi),sin(theta)*sin(phi),0,-sin(theta),cos(theta));
}
Далее в основной программе пишу

C++
1
2
3
4
5
    Matrix3d A;
    Matrix3d B;
    Matrix3d C;
 
    A = B+C;
В итоге деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. Что делать?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2014, 15:36
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Деструктор вызывается для результата сложения ДО присваивания, и дальше все падает. (C++):

При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О - C++
Вот такой кодclass A { public: A(){} virtual ~A(){} }; class C { public:

Оператор присваивания и деструктор - C++
Вопрос: почему в 52 строке Access violation? Если убрать строку 50, все будет нормально. #include &lt;iostream&gt; using namespace std; ...

Не вызывается деструктор - C++
#include &lt;iostream&gt; using namespace std; class myclass { int a; public: myclass(); // конструктор ~myclass(); //...

Деструктор не вызывается - C++
В одном классе я создаю объект, и если проверку не проходит, я его возвращаю в другой метод, дабы у меня там начало всех начал,Главное...

Не вызывается деструктор - C++
_Здравствуйте. Я новичок в программировании, сейчас изучаю самостоятельно С++ по книге Джесса Либерти. При разборе одного из примеров...

Почему вызывается деструктор? - C++
Доброго времени суток. Написал такой код: struct O { virtual ~O() { cout &lt;&lt; &quot;hey&quot;; } }; struct...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ilot
Модератор
Эксперт С++
1811 / 1168 / 229
Регистрация: 16.05.2013
Сообщений: 3,082
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 15:47 #2
Как минимум оператор Matrix3d operator+(const Matrix3d& m) должен быть friend функцией
0
Renji
1916 / 1314 / 298
Регистрация: 05.06.2014
Сообщений: 3,757
11.07.2014, 15:51 #3
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
1
Ilot
Модератор
Эксперт С++
1811 / 1168 / 229
Регистрация: 16.05.2013
Сообщений: 3,082
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:00 #4
del..
0
Renji
1916 / 1314 / 298
Регистрация: 05.06.2014
Сообщений: 3,757
11.07.2014, 16:08 #5
Зачем он тут нужен?
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
0
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
11.07.2014, 16:08 #6
Цитата Сообщение от Ilot Посмотреть сообщение
должен быть friend функцией
чеэто?
0
olper
24 / 24 / 11
Регистрация: 02.12.2013
Сообщений: 75
11.07.2014, 16:16 #7
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
  ...
    return newMatrix;
}
не надо возвращать локальную переменную, ни к чему это,
да и деструктор для всех локальных переменных при выходе из функций вызывается.
0
Renji
1916 / 1314 / 298
Регистрация: 05.06.2014
Сообщений: 3,757
11.07.2014, 16:18 #8
не надо возвращать локальную переменную, ни к чему это,
Ну и как по вашему operator+ должен вернуть результат? Глобальную переменную-приемник в него передать не получится.
да и деструктор для всех локальных переменных при выходе из функций вызывается.
Вот для этого и существует перемещающий конструктор.
0
Ilot
Модератор
Эксперт С++
1811 / 1168 / 229
Регистрация: 16.05.2013
Сообщений: 3,082
Записей в блоге: 5
Завершенные тесты: 1
11.07.2014, 16:19 #9
Цитата Сообщение от Renji Посмотреть сообщение
Затем, что return newMatrix копирует newMatrix из стека operator+ в память вызвавшей функции. И получаются два объекта владеющие одним newMatrix.matrix. Потом эти объекты пытаются свой указатель почистить и стукаются лбами.
Да туплю.
Цитата Сообщение от aLarman Посмотреть сообщение
чеэто?
Солтер стр. 498
0
zss
Модератор
Эксперт С++
6382 / 5947 / 1927
Регистрация: 18.12.2011
Сообщений: 15,264
Завершенные тесты: 1
11.07.2014, 16:28 #10
Обратите внимание, что Вы забыли написать копиконструктор!
Думаю, именно поэтому и падает!
1
Вадим Ром
0 / 0 / 1
Регистрация: 11.07.2014
Сообщений: 8
11.07.2014, 16:52  [ТС] #11
Цитата Сообщение от Renji Посмотреть сообщение
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
Спасибо большое, помогло!

Добавлено через 17 минут
Цитата Сообщение от Renji Посмотреть сообщение
C++
1
2
3
4
5
Matrix3d Matrix3d::operator+(const Matrix3d& matr){
    Matrix3d newMatrix;
...
    return newMatrix;
}
Копирующий( Matrix3d(const Matrix3d&src) )/перемещающий( Matrix3d(Matrix3d&&src) ) конструктор надо, иначе newMatrix корректно не вернется.
Спасибо, помогло
0
IrineK
Заблокирован
11.07.2014, 16:56 #12
Правило трёх
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2014, 16:56
Привет! Вот еще темы с ответами:

Почему не вызывается деструктор? - C++
Всем доброго времени суток! Подскажите пожалуйста - почему не вызывается деструктор при выполнении строки 48? #include&lt;iostream&gt;...

Не вызывается деструктор структуры - C++
Создал класс. Членом класса является указатели на структуру, которая определена в классе. Поля структуры указатели, т.к. работа будет с...

Два раза вызывается деструктор - C++
Создал класс, в процессе выполнения программы вызвал деструктор, но когда программа завершается, деструктор вызывается повторно и вылетает...

Вызывается ли деструктор в данной программе? - C++
вызывается ли деструктор в данной программе и почему он не выводит на экран,что он выведен...?#include &quot;stdafx.h&quot; #include &lt;iostream&gt; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.07.2014, 16:56
Ответ Создать тему
Опции темы

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