Сообщение Re[2]: Не компилируется Qt-проект от 31.08.2022 23:41
Изменено 31.08.2022 23:49 AleksandrN
Re[2]: Не компилируется Qt-проект
Здравствуйте, RussianFellow, Вы писали:
RF>Я убрал библиотеку libpq.lib из моего проекта и я закомментировал весь код, связанный с работой с базами данных (разбираться с этим я буду потом).
RF>После небольших изменений в файлах 3dvecmat.h и 3dvecmat.cpp -- файлы, предназначенные для работы с трехмерными векторами и трехмерными матрицами -- у меня теперь программа компилируется (собирается) и запускается.
RF>В связи с этим у меня к вам, уважаемые коллеги, вопрос: не могли бы вы посмотреть код этих файлов 3dvecmat.h и 3dvecmat.cpp и сказать, всё ли правильно в этих файлах?
RF>Файл 3dvecmat.h :
RF>
Лучше
Что бы не вызывать лишний раз конструктор копии при вызове операторов.
RF>Файл 3dvecmat.cpp :
RF>
LDouble это что? typedef для double?
В объявлении класса LDouble x,y,z; и класс попадает под определение POD-класса. Но если в будущем в классе что-то изменится или код будет перенесён на другую архитектуру, то не факт, что x,y,z будут размещены в памяти друг за другом подряд, без пропусков. Ещё нет проверки на то, что i лежит в пределах 0..2.
Лучше заменить на что то вроде
или на
Зачем делать свой swap, если ещё с C++11 есть std::swap?
Что такое 777? Если какой-нибудь код ошибки, то лучше магические числа заменить константами.
a объявлена как массив, а потом адрес одного из элементов массива приводится к указателю на класс??? Работает только потому, что это POD-класс, но это потенциальный источник больших проблем. И что будет, если i будет равно 0?
Переделать на std::array
RF>Я убрал библиотеку libpq.lib из моего проекта и я закомментировал весь код, связанный с работой с базами данных (разбираться с этим я буду потом).
RF>После небольших изменений в файлах 3dvecmat.h и 3dvecmat.cpp -- файлы, предназначенные для работы с трехмерными векторами и трехмерными матрицами -- у меня теперь программа компилируется (собирается) и запускается.
RF>В связи с этим у меня к вам, уважаемые коллеги, вопрос: не могли бы вы посмотреть код этих файлов 3dvecmat.h и 3dvecmat.cpp и сказать, всё ли правильно в этих файлах?
RF>Файл 3dvecmat.h :
RF>
RF> T3DVector& operator= (T3DVector v);
RF> T3DVector& operator+=(T3DVector v);
RF> T3DVector& operator-=(T3DVector v);
RF> T3DVector& operator*=(T3DVector v);
RF>
Лучше
T3DVector& operator= (const T3DVector &v);
T3DVector& operator+=(const T3DVector &v);
T3DVector& operator-=(const T3DVector &v);
T3DVector& operator*=(const T3DVector &v);
Что бы не вызывать лишний раз конструктор копии при вызове операторов.
RF>Файл 3dvecmat.cpp :
RF>
RF> LDouble& T3DVector::operator[](int i){return ((LDouble*)&x)[i-1];};
RF>
LDouble это что? typedef для double?
В объявлении класса LDouble x,y,z; и класс попадает под определение POD-класса. Но если в будущем в классе что-то изменится или код будет перенесён на другую архитектуру, то не факт, что x,y,z будут размещены в памяти друг за другом подряд, без пропусков. Ещё нет проверки на то, что i лежит в пределах 0..2.
Лучше заменить на что то вроде
// Вместо x,y,z.
std::array<LDouble, 3> coor;
// И добавить константы для обращения к координатам x,y,z по индексу.
enum COOR : size_t
{
X = 0,
Y,
Z
};
// И сделать operator[]
inline LDouble& T3DVector::operator[](COOR i){ return coor[i]; };
// И там, где в классе надо обращаться к координатам, писать coor[X], coor[Y], coor[Z]
или на
LDouble x,y,z;
enum COOR
{
X = 0,
Y,
Z
};
// И сделать operator[]
LDouble& T3DVector::operator[](int i)
{
switch(i)
{
case X: return x;
case Y: return y;
case Z: return z;
default: throw std::invalid_argument(std::string("Invalid index ") + std::to_string(i) + " at T3DVector::operator[]");
}
};
RF>#define swap(X,Y) tmp=(X),(X)=(Y),(Y)=tmp
RF> swap(a[0][1],a[1][0]);
RF> swap(a[0][2],a[2][0]);
RF> swap(a[1][2],a[2][1]);
RF> return *this;
RF>#undef swap
Зачем делать свой swap, если ещё с C++11 есть std::swap?
RF> throw 777;
Что такое 777? Если какой-нибудь код ошибки, то лучше магические числа заменить константами.
LDouble a[3][3];
...
T3DVector& T3DMatrix::operator[](int i) { return *(T3DVector*)a[3*(i-1)];}
a объявлена как массив, а потом адрес одного из элементов массива приводится к указателю на класс??? Работает только потому, что это POD-класс, но это потенциальный источник больших проблем. И что будет, если i будет равно 0?
Переделать на std::array
std::array<T3DVector, 3> a;
...
inline T3DVector& T3DMatrix::operator[](size_t i) { return a[i];}
Re[2]: Не компилируется Qt-проект
Здравствуйте, RussianFellow, Вы писали:
RF>Я убрал библиотеку libpq.lib из моего проекта и я закомментировал весь код, связанный с работой с базами данных (разбираться с этим я буду потом).
RF>После небольших изменений в файлах 3dvecmat.h и 3dvecmat.cpp -- файлы, предназначенные для работы с трехмерными векторами и трехмерными матрицами -- у меня теперь программа компилируется (собирается) и запускается.
RF>В связи с этим у меня к вам, уважаемые коллеги, вопрос: не могли бы вы посмотреть код этих файлов 3dvecmat.h и 3dvecmat.cpp и сказать, всё ли правильно в этих файлах?
RF>Файл 3dvecmat.h :
RF>
Лучше
Что бы не вызывать лишний раз конструктор копии при вызове операторов.
RF>Файл 3dvecmat.cpp :
RF>
LDouble это что? typedef для double?
В объявлении класса LDouble x,y,z; и класс попадает под определение POD-класса. Но если в будущем в классе что-то изменится или код будет перенесён на другую архитектуру, то не факт, что x,y,z будут размещены в памяти друг за другом подряд, без пропусков. Ещё нет проверки на то, что i лежит в пределах 0..2.
Лучше заменить на что то вроде
или на
Зачем делать свой swap, если ещё с C++11 есть std::swap?
Что такое 777? Если какой-нибудь код ошибки, то лучше магические числа заменить константами.
a объявлена как массив, а потом адрес одного из элементов массива приводится к указателю на класс??? Работает только потому, что это POD-класс, но это потенциальный источник больших проблем. Никогда не надо так делать! И что будет, если i будет равно 0?
Переделать на std::array
RF>Я убрал библиотеку libpq.lib из моего проекта и я закомментировал весь код, связанный с работой с базами данных (разбираться с этим я буду потом).
RF>После небольших изменений в файлах 3dvecmat.h и 3dvecmat.cpp -- файлы, предназначенные для работы с трехмерными векторами и трехмерными матрицами -- у меня теперь программа компилируется (собирается) и запускается.
RF>В связи с этим у меня к вам, уважаемые коллеги, вопрос: не могли бы вы посмотреть код этих файлов 3dvecmat.h и 3dvecmat.cpp и сказать, всё ли правильно в этих файлах?
RF>Файл 3dvecmat.h :
RF>
RF> T3DVector& operator= (T3DVector v);
RF> T3DVector& operator+=(T3DVector v);
RF> T3DVector& operator-=(T3DVector v);
RF> T3DVector& operator*=(T3DVector v);
RF>
Лучше
T3DVector& operator= (const T3DVector &v);
T3DVector& operator+=(const T3DVector &v);
T3DVector& operator-=(const T3DVector &v);
T3DVector& operator*=(const T3DVector &v);
Что бы не вызывать лишний раз конструктор копии при вызове операторов.
RF>Файл 3dvecmat.cpp :
RF>
RF> LDouble& T3DVector::operator[](int i){return ((LDouble*)&x)[i-1];};
RF>
LDouble это что? typedef для double?
В объявлении класса LDouble x,y,z; и класс попадает под определение POD-класса. Но если в будущем в классе что-то изменится или код будет перенесён на другую архитектуру, то не факт, что x,y,z будут размещены в памяти друг за другом подряд, без пропусков. Ещё нет проверки на то, что i лежит в пределах 0..2.
Лучше заменить на что то вроде
// Вместо x,y,z.
std::array<LDouble, 3> coor;
// И добавить константы для обращения к координатам x,y,z по индексу.
enum COOR : size_t
{
X = 0,
Y,
Z
};
// И сделать operator[]
inline LDouble& T3DVector::operator[](COOR i){ return coor[i]; };
// И там, где в классе надо обращаться к координатам, писать coor[X], coor[Y], coor[Z]
или на
LDouble x,y,z;
enum COOR
{
X = 0,
Y,
Z
};
// И сделать operator[]
LDouble& T3DVector::operator[](int i)
{
switch(i)
{
case X: return x;
case Y: return y;
case Z: return z;
default: throw std::invalid_argument(std::string("Invalid index ") + std::to_string(i) + " at T3DVector::operator[]");
}
};
RF>#define swap(X,Y) tmp=(X),(X)=(Y),(Y)=tmp
RF> swap(a[0][1],a[1][0]);
RF> swap(a[0][2],a[2][0]);
RF> swap(a[1][2],a[2][1]);
RF> return *this;
RF>#undef swap
Зачем делать свой swap, если ещё с C++11 есть std::swap?
RF> throw 777;
Что такое 777? Если какой-нибудь код ошибки, то лучше магические числа заменить константами.
LDouble a[3][3];
...
T3DVector& T3DMatrix::operator[](int i) { return *(T3DVector*)a[3*(i-1)];}
a объявлена как массив, а потом адрес одного из элементов массива приводится к указателю на класс??? Работает только потому, что это POD-класс, но это потенциальный источник больших проблем. Никогда не надо так делать! И что будет, если i будет равно 0?
Переделать на std::array
std::array<T3DVector, 3> a;
...
inline T3DVector& T3DMatrix::operator[](size_t i) { return a[i];}