Перегрузка функции копирования C ++ приводит к ошибке «должна быть нестатическая функция-член» - PullRequest
0 голосов
/ 30 сентября 2018

У меня ошибка при попытке скомпилировать мой код.Код перегружает операторы, и все перегруженные операторы работали, пока я не попытался назначить конструктор копирования.Я продолжаю получать сообщение об ошибке «Оператор MyClass = (const MyClass &)« должен быть нестатической функцией-членом »).Я не понимаю, почему перегрузка оператора "=" может вызвать такую ​​ошибку.Помещение специального слова «друг» перед объявлением в файле .h не решает проблему.

main.cpp

#include <iostream>
#include "Point.h"
using namespace std;


int main() {

   Point point1( 2, 5);
   Point point2 = point1;
   return 0;

}

MyClass.h

 #ifndef POINT_H_
 #define POINT_H_

 #include <iostream>
 #include <cmath>

 using namespace std;

 class Point {

  public:
    //Constructor
    Point();
    Point(const double x, const double y);

    //Copy
    Point(const Point & t);

    //Destructor
    virtual ~Point();

    //Get the x value
    double getX() const;

    //Get the y value
    double getY() const;

    //Set the x value
    void setX(double x);

    //Set the y value
    void setY(double y);

    //Return the distance between Points
    double distance(const Point& p) const;

    //Output the Point as (x, y) to an output stream
    friend ostream& operator << (ostream& out, const Point& point);

    //Comparison relationships
    friend bool operator == (const Point& lhs, const Point& rhs);
    friend bool operator < (const Point& lhs, const Point& rhs);

    //Math operators
    friend Point operator + (const Point& lhs, const Point& rhs);
    friend Point operator - (const Point& lhs, const Point& rhs);

    Point& operator = (const Point& rhs);

 private:
    double x;
    double y;
 };
 #endif /* POINT_H_ */

MyClass.cpp

 // Get the x value
 double Point::getX() const {
   return x;
 }

 // Get the y value
 double Point::getY() const {
   return y;
 }

 void Point::setX(double x) {
   this->x = x;
 }

 void Point::setY(double y) {
   this->y = y;
 }

 // Return the distance between Points
 double Point::distance(const Point& p) const{
   return abs( sqrt( pow( (x - p.getX() ), 2 ) + pow( (y - p.getY() ), 2 ) ) );
 }

 ostream& operator << (ostream& out, const Point& point){
   out << point.getX() << ", " << point.getY();
   return out;
 }

 bool operator == (const Point& lhs, const Point& rhs){
   if(lhs.x == rhs.x && lhs.y == rhs.y){ return true; }
   return false;
 }

 bool operator < (const Point& lhs, const Point& rhs){
   if(lhs.x < rhs.x && lhs.y < rhs.y){ return true; }
   return false;
 }

 Point operator + (const Point& lhs, const Point& rhs){
   Point point;
   point.x = lhs.x + rhs.x;
   point.y = lhs.y + rhs.y;

   return point;
 }

 Point operator - (const Point& lhs, const Point& rhs){
   Point point;
   point.x = lhs.x - rhs.x;
   point.y = lhs.y - rhs.y;

   return point;
 }

 Point& Point::operator = (const Point& rhs){
   x = rhs.x;
   y = rhs.y;
   return *this;
 }

 // Destructor
 Point::~Point(){}

1 Ответ

0 голосов
/ 30 сентября 2018

Здесь есть ряд проблем, которые я постараюсь устранить, одну за другой.

Что касается вашего основного вопроса, поскольку оператор присваивания копии определен внутри области действия MyClass, вам также необходимо записать его определение как область видимости внутри MyClass, просто добавив MyClass:: перед именем функции, как вы бы с любой другой областью.Далее, вам действительно нужно скопировать данные rhs в this, и вы должны вернуть ссылку на *this.

MyClass& MyClass::operator=(const MyClass& rhs){
    x = rhs.x;
    y = rhs.y;
    return *this;
}

Если вы скопируете rhs во временный файл и вернете это, вся семантика назначения копирования полностью нарушена.Это приведет к следующим вещам:

MyClass obj1 {999.0, 2468.0};
MyClass obj2 {0.0, 0.0};
obj2 = obj1; // should copy obj1 to obj2
cout << obj2.x << " " << obj2.y << '\n'; // outputs "0.0 0.0" ??!?!?

Также имейте в виду, что это тривиальный конструктор копирования, вы можете полностью удалить его, так как компилятор неявно сгенерирует для вас тот же самый, который выполняет член-член.мудрая копия, которая в этом случае полностью безопасна.См. специальные функции-члены .

В вашем operator+ теле функции есть следующие строки:

MyClass myVar;
MyClass.x = lhs.x + rhs.x;
MyClass.y = lhs.y + rhs.y;
return myVar;

Вы, вероятно, имеете в виду myVar.x и myVar.y.MyClass относится только к типу, а попытка доступа MyClass.x - бессмысленное утверждение.

Как правило, вы никогда не должны возвращать ссылку на временный объект, как в вашей текущей реализации.Локальные объекты уничтожаются при возврате функции, и это оставляет вам висячую ссылку на уничтоженный объект, память которого, скорее всего, будет перезаписана полным мусором в ближайшем будущем. Здесь - хорошее объяснение того, что происходит.

Дайте мне знать, если у вас возникнут какие-либо проблемы или что-то неясно после прочтения ссылок.Удачного кодирования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...