0

我设法了解如何将重载运算符实现为成员函数。这种方式认为对象(实例)始终传递给操作员。为了让它工作,我在类外定义了我的重载运算符。仅当我在头文件(.hpp)中定义它时才有效。如果我将函数添加到 .cpp 文件,为什么编译器会忽略它?一段代码如下:

//class.hpp
#ifndef POINT_H_
#define POINT_H_

template<class T>
class point{
    public:
      point(T&x,T&y);
      point<T> operator*(T& lambda);
      point<T> operator=(const point<T>& P);
      void print();
    private:
        T&x_;
    T&y_;
};
#endif
//class.cpp
#include<iostream>
#include "point.hpp"
template<class T>
point<T>::point(T&x,T&y)
:
x_(x),
y_(y)
{
}

template<class T>
point<T> point<T>::operator*(T& lambda){
    x_*=lambda;
    y_*=lambda;
    return *this;
}

template <class T>
point<T> point<T>::operator = (const point<T> & P){
    this->x_=P.x_;
    this->y_=P.y_;
  return *this;
}

template<class T>
void point<T>::print(){
    std::cout<<"X is "<<this->x_<<" Y is "<<this->y_<<"\n";
}

template class point<int>;
template class point<double>;

template<class T>
  point<T> operator*(T& lambda,point<T>& P)
  {
    return P*lambda;
  }

下面显示的最后一个函数仅在我将其添加到头文件时才有效。

template<class T>
  point<T> operator*(T& lambda,point<T>& P)
  {
    return P*lambda;
  }

主文件是

#include<iostream>

#include "point.hpp"

int main(){
    
    double a=3.0;
    double b=4.0;

    point<double> X = point<double>(a,b);
    double m=3.0;
    X=m*X;
    X.print();

    return 0;
}

编译错误是

'operator*' 不匹配(操作数类型为 'double' 和 'point') X=m*X;

如果我在头文件中重载乘法运算符,则重载可以从双点或双点两个方向正常工作。

4

1 回答 1

0

C++ 需要在头文件(通常是 .h/.hpp)中声明一个函数,以便从不同的源文件 (.cpp) 中使用它。所以你必须把声明

template<class T>
point<T> operator*(T& lambda,point<T>& P);

在您包含的标题(point.hpp)中。

顺便说一句,您对运算符的实现是错误的,因为计算X * m(或m * X)会改变X自身,这通常是不希望的。所以你应该将 operator* 实现为

template<class T>
point<T> point<T>::operator*(T& lambda){
    return point<T>(x_*lambda,y_*lambda);
}

或者您可以将 operator*= 定义为

template<class T>
point<T>& point<T>::operator*=(T& lambda){
    x_*=lambda;
    y_*=lambda;
    return *this;
}

并做X*=m而不是X=m*X

于 2021-07-16T17:24:05.467 回答