首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++运算符及重载有关问题,求大神指点及改正

2013-01-04 
C++运算符及重载问题,求大神指点及改正/*#include ComPlexNum.h*/#include iostream#include iomanip

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返回整形。
}

[解决办法]
應該是你用template 重載<<出了問題
template <class T>
ostream& operator<< (ostream& os ,const cnum<T> &N1)  //這裡定義要和你的聲明一致,const 不能去掉


{

const cnum<T>  //這個T被默認為int了。

所以叫你不要用template,

你堅持用的話,等樓下的解決方案吧,我不知道如何改了,
看有沒有人知道,一起學習。C++运算符及重载有关问题,求大神指点及改正

[解决办法]
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了,
就不是这个类的成员了。

template <class T>
class cnum
{
template<class V>
friend ostream& operator<< (ostream &os ,const cnum<V> &N1) ;
template<class V>
friend const double Val (const cnum<V> &N1) ;//返回复数的模
private:
……
};

template <class V>
const double Val (const cnum<V> &N1)
{
……
}

template <class V>
ostream& operator<< (ostream& os ,const cnum<V> &N1)
{
……
[解决办法]
>问题一:
>friend const double Val (const cnum<U> &N1) ;//返回复数的模改成


>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,因为后者是类模板参数类型名称,避免不必要的名称覆盖。

热点排行