C++运算符及重载问题,求大神指点及改正
/*#include "ComPlexNum.h"*/
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std ;
bool ERROR = false ;//初始化
template <class T>
class cnum
{
friend ostream& operator<< <T>(ostream &os ,const cnum<T> &N1) ;
friend const double Val (const cnum<T> &N1) ;//返回复数的模
private:
T real ;//实部
T image ;//虚部
public:
cnum (): real(0) ,image(0) {};
cnum (const int real ,const int image)
{this->real = real ; this->image = image ; };
};
template <class T>
const double Val (const cnum<T> &N1)
{
T tmp ;
tmp = N1.real * N1.real + N1.image * N1.image ;
return (sqrt((double)tmp)) ;
}
template <class T>
ostream& operator<< (ostream& os ,/*const*/ cnum<T> &N1)
{
if(ERROR)
return (os) ;
if(!Val(N1))
{
cout<<0<<endl ;
return (os) ;
}
if(N1.real)
os<<N1.real ;
if(N1.image > 0)
{
if(N1.image == 1)
os<<"+"<<"i"<<endl ;
else
os<<"+"<<N1.image<<"i"<<endl ;
}
else if(N1.image < 0)
{
if(N1.image == -1)
os<<"-"<<"i"<<endl ;
else
os<<N1.image<<"i"<<endl ;
}
else
os<<endl ;
return (os) ;
}
void main()
{
cnum<int> n1(12,2) ;
cout<<n1 ;
system("pause") ;
}
[解决办法]
/*#include "ComPlexNum.h"*/
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
bool ERROR = false ;//初始化
template <class T>
class cnum
{
friend ostream& operator<< (ostream &os ,const cnum<T> &N1) ;
friend const double Val (const cnum<T> &N1) ;//返回复数的模
public:
T real ; //实部
T image ; //虚部
public:
cnum (): real(0) ,image(0) {};
cnum (const int real ,const int image)
{this->real = real ; this->image = image ; };
};
template <class T>
const double Val (const cnum<T> &N1)
{
T tmp ;
tmp = N1.real * N1.real + N1.image * N1.image ;
return (sqrt((double)tmp)) ;
}
template <class T>
ostream& operator<< (ostream& os ,/*const*/ cnum<T> &N1)
{
if(ERROR)
return (os) ;
if(!Val(N1))
{
cout<<0<<endl ;
return (os) ;
}
if(N1.real)
os<<N1.real ;
if(N1.image > 0)
{
if(N1.image == 1)
os<<"+"<<"i"<<endl ;
else
os<<"+"<<N1.image<<"i"<<endl ;
}
else if(N1.image < 0)
{
if(N1.image == -1)
os<<"-"<<"i"<<endl ;
else
os<<N1.image<<"i"<<endl ;
}
else
os<<endl ;
return (os) ;
}
void main()
{
cnum<int> n1(12,2) ;
cout<<n1 ;
system("pause") ;
}
[解决办法]
帮你看了一下,是friend ostream& operator<< <T>(ostream &os ,const cnum<T> &N1) ;定义的问题吧
[解决办法]
幫你改了一下,具體請看下面的代碼中增加的註解。
強烈建議你不要用template,將T改回double重新寫一遍吧!
/*#include "ComPlexNum.h"*/
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdlib.h>
using namespace std ;
bool ERROR = false ;//初始化
template <class T> //不知道你爲什麽用template, 這裡根本沒必要,直接用double就很好。
class cnum
{
public: //友元函數應作爲public
friend ostream& operator<< /*<T>*/(ostream &os ,const cnum<T> &N1) ; // <T> 不需要
friend /*const*/ double Val (const cnum<T> &N1) ;//返回复数的模 //const不能那裏都用的。
private:
T real ;//实部
T image ;//虚部
public:
cnum (): real(0) ,image(0) {};
cnum (const int real ,const int image)
{this->real = real ; this->image = image ; };
};
template <class T>
/*const*/ double Val (const cnum<T> &N1)
{
T tmp ;
tmp = N1.real * N1.real + N1.image * N1.image ;
return (sqrt((double)tmp)) ; //你這裡又將T強制轉爲double,
}
template <class T>
ostream& operator<< (ostream& os ,const cnum<T> &N1) //這裡定義要和你的聲明一致,const 不能去掉
{
if(ERROR)
return (os) ;
if(!Val(N1))
{
cout<<0<<endl ;
return (os) ;
}
if(N1.real)
os<<N1.real ;
if(N1.image > 0)
{
if(N1.image == 1)
os<<"+"<<"i"<<endl ;
else
os<<"+"<<N1.image<<"i"<<endl ;
}
else if(N1.image < 0)
{
if(N1.image == -1)
os<<"-"<<"i"<<endl ;
else
os<<N1.image<<"i"<<endl ;
}
else
os<<endl ;
return (os) ;
}
int main()
{
cnum<int> n1(12,2) ;
cout<<n1 ;
system("pause") ;
return 0; //現代編譯器都要求main返回整形。
}
{
const cnum<T> //這個T被默認為int了。
所以叫你不要用template,
你堅持用的話,等樓下的解決方案吧,我不知道如何改了,
看有沒有人知道,一起學習。
[解决办法]
here is a working code with template class / friend template functions.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
bool ERROR = false;//初始化
template <class T>
class cnum
{
template <typename U>
friend ostream& operator<< (ostream &os, const cnum<U> &N1);
template <typename U>
friend double Val (const cnum<U> &N1);//返回复数的模
private:
T real; //实部
T image; //虚部
public:
cnum (): real(0) ,image(0) {};
cnum (const int real ,const int image)
{this->real = real; this->image = image; }
};
template <class T>
double Val (const cnum<T> &N1)
{
T tmp;
tmp = N1.real * N1.real + N1.image * N1.image;
return (sqrt((double)tmp));
}
template <class T>
ostream& operator << (ostream& os, const cnum<T> &N1)
{
if(ERROR)
return (os);
if(!Val(N1))
{
cout<<0<<endl;
return (os);
}
if(N1.real)
os<<N1.real;
if(N1.image > 0)
{
if(N1.image == 1)
os<<"+"<<"i"<<endl;
else
os<<"+"<<N1.image<<"i"<<endl;
}
else if(N1.image < 0)
{
if(N1.image == -1)
os<<"-"<<"i"<<endl;
else
os<<N1.image<<"i"<<endl;
}
else
os<<endl;
return (os);
}
int main()
{
cnum<int> n1(12,2);
cout<<n1;
system("pause");
return 0;
}
>friend double Val (const cnum<U> &N1) ;去掉了const了才正确
加 const 也行,只不过 const 没用,prototype adjustment 以后所有顶层 cv-qualification 都去掉的;另外,在 c++11 move semantics 下,给返回值加 const 反而是不好的习惯。
>问题二:
>friend istream& operator>> (istream &ins ,cnum<T> &N1) ;
>template <typename U> //此声明不可少
>friend ostream& operator<< (ostream &os ,const cnum<U> &N1) ;
>这两个都是友元模板及运算符重载,为什么重载">>"时可以不需要语句“template ><typename U>”,而重载"<<"时需要加上"template <typename U>"?
operator << 按你给的第一种写法也可以,实际上一般都是这么写。只不过我看你主楼程序貌似希望用模板的写法,才写成模板的。两者的区别是,第一种写法声明的是友元函数,第二种是友元函数模板。
>问题三:
>template <typename U>有什么作用,跟这里的模板有什么关系?
只是说明下面的是模板函数声明,不是普通函数声明,这里可以用任何合法字符,只不过不要用 T,因为后者是类模板参数类型名称,避免不必要的名称覆盖。