注册 登录
编程论坛 C++教室

c++友元重载运算符的模板类实现问题

水桃蜜蜜 发布于 2016-05-11 19:39, 6157 次点击
知道把友元函数体放到类声明内部,使其跟着类的实例化一同实例化,可以使友元重载运算符函数运行成功。但是如果将重载运算符的定义分开书写。则会出错。求解。
#include <iostream>
using namespace std;
//发现重载运算符函数写在定义友函数时没有,但分离便有错值得注意
//有空找原因
template <class T>
class Complex
{
public:
    Complex(){real=0;imag=0;}
    Complex(T r,T i):real(r),imag(i){}
    Complex(double r){real=r;imag=0;}
    friend Complex operator +(Complex c1,Complex c2)
    {
        return Complex(c1.real+c2.real,c1.imag+c2.imag);
    }
   friend Complex operator -(Complex c1,Complex c2)
   {
    return Complex(c1.real-c2.real,c1.imag-c2.imag);
}
   friend Complex operator *(Complex c1,Complex c2)
   {
    return Complex(c1.real*c2.real-c1.imag*c2.imag,c1.real*c2.imag+c1.imag*c2.real);
}
   friend Complex operator /(Complex c1,Complex c2)
   {
       Complex c3;
    c3.real=(c1.real*c2.real-c1.imag*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag);
    c3.imag=(c1.real*c2.imag+c1.imag*c2.real)/(c2.real*c2.real+c2.imag*c2.imag);
    return c3;
   }
   friend istream&operator>>(istream&input,Complex <T>&obj)
   {
    input>>obj.real>>obj.imag;
    return input;
}
   friend ostream& operator<<(ostream &output,Complex<T> &obj)
   {
    output<<"("<<obj.real<<"+"<<obj.imag<<"i)";
    return output;
    }
 private:
    T real;
    T imag;
};


int main()
{
    Complex<double> obj_1(1,2);
    Complex<double> obj_2(1,2);
    Complex<double> obj_3;
    obj_3=obj_1+obj_2;
    cout<<"obj_3=obj_1+obj2=";cout<<obj_3<<endl;
    obj_3=obj_1-obj_2;
    cout<<"obj_3=obj_1-obj2=";cout<<obj_3<<endl;
    obj_3=obj_1*obj_2;
    cout<<"obj_3=obj_1*obj2=";cout<<obj_3<<endl;
    obj_3=obj_1/obj_2;
    cout<<"obj_3=obj_1/obj2=";cout<<obj_3<<endl;
    obj_3=obj_1+2.5;
    cout<<"obj_3=obj_1+2.5=";cout<<obj_3<<endl;
    obj_3=2.5+obj_1;
    cout<<"obj_3=2.5+obj_1=";cout<<obj_3<<endl;
    return 0;
}
6 回复
#2
水桃蜜蜜2016-05-11 21:32
上面是一个友元重载运算符函数,定义在内部且运行成功的案例。但是我不会将定义重载运算符定义在外部
#3
rjsp2016-05-12 08:39
既然说“但是如果将重载运算符的定义分开书写。则会出错。”,那么为什么不给出你所谓出错的代码呢?
照着正确的代码,即使看千遍,又怎么能猜到你错误的代码是怎么写错的呢?

我随便举个例子
程序代码:
template<class T> class Complex
{
public:
    Complex() : real_(0), image_(0)
    {
    }
    Complex( T real, T image ) : real_(real), image_(image)
    {
    }
private:
    T real_;
    T image_;

    template<class U> friend Complex<U> operator+( const Complex<U>& c1, const Complex<U>& c2 );
};

template<class U> Complex<U> operator+( const Complex<U>& c1, const Complex<U>& c2 )
{
    return Complex<U>( c1.real_+c2.real_, c1.image_+c2.image_ );
}

int main( void )
{
    Complex<double> a( 1, 2 );
    Complex<double> b( 3, 4 );
    a + b;

    return 0;
}

#4
水桃蜜蜜2016-05-12 19:06
回复 3楼 rjsp
我大体知道了。类的虚拟类型名和重载运算符的虚拟类型名不一样就是对的。可是为什么呀,如下就是错的。求解释。显示的错误为:
D:\C++\text\main.cpp|32|undefined reference to `operator+(Complex<double> const&, Complex<double> const&)'|
#include <iostream>
using namespace std;
template<class T>
 class Complex
 {
public:
     Complex() : real_(0), image_(0)
     {
     }
     Complex( T real, T image ) : real_(real), image_(image)
     {
     }
private:
     T real_;
     T image_;
//template<class T>如果在这里有template<class T>,也会显示错误。错误为:D:\C++\text\main.cpp|18|error: declaration of 'class T'|
     friend Complex<T> operator+( const Complex<T>& c1, const Complex<T>& c2 );
 };
template<class T>
Complex<T> operator+( const Complex<T>& c1, const Complex<T>& c2 )
 {
     return Complex<T>( c1.real_+c2.real_, c1.image_+c2.image_ );
 }
int main( void )
 {
     Complex<double> a( 1, 2 );
     Complex<double> b( 3, 4 );
     a + b;   
    return 0;
 }
#5
rjsp2016-05-13 08:17
回复 4楼 水桃蜜蜜
程序代码:
template<class T> class Complex;
template<class T> Complex<T> operator+( const Complex<T>& c1, const Complex<T>& c2 );

template<class T> class Complex
{
public:
    Complex() : real_(0), image_(0)
    {
    }
    Complex( T real, T image ) : real_(real), image_(image)
    {
    }
private:
    T real_;
    T image_;
    friend Complex<T> operator+<T>( const Complex<T>& c1, const Complex<T>& c2 );
};

template<class T> Complex<T> operator+( const Complex<T>& c1, const Complex<T>& c2 )
{
    return Complex<T>( c1.real_+c2.real_, c1.image_+c2.image_ );
}

int main( void )
{
    Complex<double> a( 1, 2 );
    Complex<double> b( 3, 4 );
    a + b;
    return 0;
}

#6
水桃蜜蜜2016-05-13 19:31
回复 5楼 rjsp
有error。运行不成功,用vc++和codeblocks都不行。能不能再解释一下我在三楼提的问题
#7
水桃蜜蜜2016-05-18 19:54
回复 3楼 rjsp
人还在吗。能解释一下为什么类的模板名不能友元重载运算符函数的一样吗
1