Произошла ошибка при построении класса 3D-векторов

Я отлаживаю трехмерный векторный код, но получаю следующую ошибку

/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

конструктор копирования должен быть cvector(const cvector&)

463035818_is_not_an_ai 21.06.2023 09:46

Добавьте const ко всем неизменяемым функциям-членам, таким как cvector operator +(cvector x1) const и double dist(cvector x1) const.

n. m. will see y'all on Reddit 21.06.2023 09:48

В C++ нельзя игнорировать const.

john 21.06.2023 10:42

В cvector нет необходимости в определяемом пользователем конструкторе копирования. Все, что вы делаете, предоставляя одну, — это способ внесения ошибок — что, если вы введете другую переменную-член и забыли скопировать ее в свой пользовательский конструктор? Все члены являются double, поэтому класс сам по себе является безопасным для копирования, т. е. конструктор копирования по умолчанию, сгенерированный компилятором, отлично работает, работает правильно и не будет приводить к ошибкам. Итог - удалите конструктор копирования до тех пор, пока вам действительно не понадобится его добавить.

PaulMcKenzie 21.06.2023 11:05
friend cvector cross(cvector x1, cvector x2) -- Если вы привыкли к Python, Java, C# или подобным языкам, это не делает то, что вы думаете, когда речь идет о C++. Эти параметры не создают ссылок на переданный cvector — вместо этого создаются временные копии. Если вам нужны ссылки на C++, вы должны явно указать это с помощью оператора ссылки &. Это одна большая ошибка, которую допускают программисты, пришедшие из других языков, и заключается в том, что они думают, что передача параметров работает так же, как и в этих других языках.
PaulMcKenzie 21.06.2023 11:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Конструктор копирования 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», которое является именованной переменной.

В этом случае созданный объект не является именованной переменной.

Слон в комнате заключается в том, что нет необходимости в определяемом пользователем конструкторе копирования.

PaulMcKenzie 21.06.2023 11:06

да, конструкции по умолчанию может быть достаточно

Zig Razor 21.06.2023 11:42

Другие вопросы по теме