Я отлаживаю трехмерный векторный код, но получаю следующую ошибку
/usr/bin/g++ -fdiagnostics-color=always -g /home/fangrui/vectorFEM/vectorFEM/main.cpp -o /home/fangrui/vectorFEM/vectorFEM/main
In file included from /home/fangrui/vectorFEM/vectorFEM/constant.h:6:0,
from /home/fangrui/vectorFEM/vectorFEM/mesh.h:2,
from /home/fangrui/vectorFEM/vectorFEM/edgenedelec.h:2,
from /home/fangrui/vectorFEM/vectorFEM/main.cpp:1:
/home/fangrui/vectorFEM/vectorFEM/cvector3D.h: In function ‘cvector operator*(double, cvector)’:
/home/fangrui/vectorFEM/vectorFEM/cvector3D.h:39:10: error: cannot bind non-const lvalue reference of type ‘cvector&’ to an rvalue of type ‘cvector’
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
Это проблема в файле cvector3D.h
, но я не понимаю, что это за ошибка и какие изменения должны быть сделаны. В дополнение к ошибке выше, также есть предупреждение о friend
:
class "cvector" has no suitable copy constructorC/C++(334)
вот исходный код для cvector3D.h
# ifndef CVECTOR3D_H
# define CVECTOR3D_H
#include<cmath>
#include<ostream>
#include<iomanip>
using namespace std;
/*A three-dimensional real vector class is defined to facilitate numerical calculations*/
class cvector
{
public:
double x, y, z;
//Construct function
cvector(double _x, double _y, double _z){ x = _x; y = _y; z = _z; }
//Copy the constructor
cvector(cvector &pt){ x = pt.x; y = pt.y; z = pt.z; }
cvector(){ x = 0; y = 0; z = 0; }
~cvector(){};
//Operator overloading
cvector operator +();
cvector operator -(); //The vector is negated
friend ostream &operator<<(ostream &os, const cvector &x1);
cvector operator +(cvector x1);
cvector operator -(cvector x1);
cvector operator *(double x1);
cvector operator /(double x1);
cvector &operator =(cvector x1);
cvector &operator +=(cvector x1);
cvector &operator -=(cvector x1);
cvector &operator *=(double x1);
cvector &operator /=(double x1);
int operator ==(cvector x1);
int operator !=(cvector x1);
friend cvector operator *(double x1, cvector x2) {
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
}
//Member functions
double dist(cvector x1);
cvector unit();
double norm();
friend cvector cross(cvector x1, cvector x2)
{
return cvector(x1.y*x2.z - x1.z*x2.y, x1.z*x2.x - x1.x*x2.z, x1.x*x2.y - x1.y*x2.x);
}
friend double dot(cvector x1, cvector x2)
{
return (x1.x*x2.x + x1.y*x2.y + x1.z*x2.z);
}
} ;
# endif
Добавьте const
ко всем неизменяемым функциям-членам, таким как cvector operator +(cvector x1) const
и double dist(cvector x1) const
.
В C++ нельзя игнорировать const
.
В cvector
нет необходимости в определяемом пользователем конструкторе копирования. Все, что вы делаете, предоставляя одну, — это способ внесения ошибок — что, если вы введете другую переменную-член и забыли скопировать ее в свой пользовательский конструктор? Все члены являются double
, поэтому класс сам по себе является безопасным для копирования, т. е. конструктор копирования по умолчанию, сгенерированный компилятором, отлично работает, работает правильно и не будет приводить к ошибкам. Итог - удалите конструктор копирования до тех пор, пока вам действительно не понадобится его добавить.
friend cvector cross(cvector x1, cvector x2)
-- Если вы привыкли к Python, Java, C# или подобным языкам, это не делает то, что вы думаете, когда речь идет о C++. Эти параметры не создают ссылок на переданный cvector
— вместо этого создаются временные копии. Если вам нужны ссылки на C++, вы должны явно указать это с помощью оператора ссылки &
. Это одна большая ошибка, которую допускают программисты, пришедшие из других языков, и заключается в том, что они думают, что передача параметров работает так же, как и в этих других языках.
Конструктор копирования cvector
имеет неправильный формат.
Правильная форма cvector(const cvector& cvec)
.
Длинное описание:
Когда функция друга
friend cvector operator *(double x1, cvector x2) {
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
}
называется конструктор cvector
называется.
Сразу после того, как сконструированный объект возвращается копированием, вызывается конструктор копирования, но только что созданное lvalue типа cvector&
, то есть non-const
, не может быть преобразовано в rvalue типа cvector
.
Это связано с тем, что неконстантный ссылочный параметр, такой как, например, int&,
, может ссылаться только на «lvalue», которое является именованной переменной.
В этом случае созданный объект не является именованной переменной.
Слон в комнате заключается в том, что нет необходимости в определяемом пользователем конструкторе копирования.
да, конструкции по умолчанию может быть достаточно
конструктор копирования должен быть
cvector(const cvector&)