C++,重载输出操作符<<, cout.operator()

C++,重载输出操作符<<, cout.operator()是什么东东?

标签: c++stringincludeos
5701人阅读 评论(1) 收藏 举报
本文章已收录于:
分类:

 

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. class Student  
  6. {  
  7. public:  
  8.     // 存  
  9.     void setname(string s){ name = s;}  
  10.     void setage(int y){age = y; }  
  11.     void setaddress(string add){address = add;}      
  12.     // 取  
  13.     string getname(){return name;}  
  14.     int getage(){return age;}  
  15.     string getaddress(){return address;}  
  16.      
  17.     Student(string name="",int age=0,string address="")  
  18.     {  
  19.         this->name = name; this->age = age; this->address = address;        
  20.     }  
  21.     ~Student(){}  
  22.   
  23.       
  24.      //重载 运算符<< : 把 "operator<<" 看作是函数名, 返回类型是 ostream类型的对象引用  
  25.     friend ostream& operator<< (ostream &os,Student &st)  
  26.     {  
  27.         os<<st.name<<"------"<<st.age<<"------"<<st.address<<endl;  
  28.         return os;  
  29.     }  
  30. protected:    
  31. private:  
  32.     string name;  
  33.     int    age;  
  34.     string address;  
  35. };  
  36.   
  37. void main()  
  38. {   
  39. Student x1("刘莉莉",22,"东风路369号");   
  40.  cout<<x1;   
  41. //cout<<x1 ---结果OK,问题是这个写法很怪,是谁在调用那个重载函数?,x1显然是个参数,那是cout调用的 operator<< ?   
  42.        
  43.   
  44.       /* 
  45.          "<<"  是个什么东东? C++ Prime P6 
  46.         这是个 "输出操作符", 其左边是ostream对象cout,右边是要输出的值 
  47.         它的操作返回输出流本身cout,也就是可以连续写的原因. 
  48.  
  49.        */  
  50.   
  51.       // 既然 cout是 ostream对象,那么可以用 . 的形式 访问ostream的成员函数  
  52.       // 但是 operator<< 在本程序中已经重载了,要按照本程序的形参格式传入参数 ?  
  53.        ostream z;  
  54.        cout.operator<<(z,x1);  // 编译通不过...  
  55. }  
#include <iostream>
#include <string>
using namespace std;

class Student
{
public:
	// 存
	void setname(string s){	name = s;}
	void setage(int y){age = y;	}
	void setaddress(string add){address = add;}    
	// 取
	string getname(){return name;}
	int getage(){return age;}
	string getaddress(){return address;}
   
	Student(string name="",int age=0,string address="")
	{
		this->name = name; this->age = age; this->address = address;      
	}
	~Student(){}

    
	 //重载 运算符<< : 把 "operator<<" 看作是函数名, 返回类型是 ostream类型的对象引用
	friend ostream& operator<< (ostream &os,Student &st)
	{
		os<<st.name<<"------"<<st.age<<"------"<<st.address<<endl;
		return os;
	}
protected:	
private:
	string name;
	int    age;
	string address;
};

void main()
{ 
Student x1("刘莉莉",22,"东风路369号"); 
 cout<<x1; 
//cout<<x1 ---结果OK,问题是这个写法很怪,是谁在调用那个重载函数?,x1显然是个参数,那是cout调用的 operator<< ? 
     

	  /*
	     "<<"  是个什么东东? C++ Prime P6
		这是个 "输出操作符", 其左边是ostream对象cout,右边是要输出的值
		它的操作返回输出流本身cout,也就是可以连续写的原因.

	   */

	  // 既然 cout是 ostream对象,那么可以用 . 的形式 访问ostream的成员函数
      // 但是 operator<< 在本程序中已经重载了,要按照本程序的形参格式传入参数 ?
       ostream z;
	   cout.operator<<(z,x1);  // 编译通不过...
}


//---

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. void main()  
  6. {   
  7.   cout.operator <<("csdn"); // 0046E01,是个地址? 为什么不是输出字符串"csdn"?  
  8. }  
#include <iostream>
#include <string>
using namespace std;

void main()
{ 
  cout.operator <<("csdn"); // 0046E01,是个地址? 为什么不是输出字符串"csdn"?
}


 // ---  答案.....

http://topic.csdn.net/u/20121006/15/eba3d438-2f71-4b39-b8d5-f6c4a94e3d1b.html?seed=131699817&r=79821898#r_79821898

 

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. class Student  
  6. {  
  7. public:  
  8.     // 存  
  9.     void setname(string s){ name = s;}  
  10.     void setage(int y){age = y; }  
  11.     void setaddress(string add){address = add;}      
  12.     // 取  
  13.     string getname(){return name;}  
  14.     int getage(){return age;}  
  15.     string getaddress(){return address;}  
  16.       
  17.     Student(string name="",int age=0,string address="")  
  18.     {  
  19.         this->name = name; this->age = age; this->address = address;        
  20.     }  
  21.     ~Student(){}  
  22.       
  23.       
  24.     //重载 运算符<< : 把 "operator<<" 看作是函数名, 返回类型是 ostream类型的对象引用  
  25.     friend ostream& operator<< (ostream &os,Student &st)  
  26.     {  
  27.         os<<st.name<<"------"<<st.age<<"------"<<st.address<<endl;  
  28.         return os;  
  29.     }  
  30. protected:    
  31. private:  
  32.     string name;  
  33.     int    age;  
  34.     string address;  
  35. };  
  36.   
  37. void main()  
  38. {   
  39.     Student x1("刘莉莉",22,"东风路369号");   
  40.     cout<<x1;   
  41.     //cout<<x1 ---结果OK,问题是这个写法很怪,是谁在调用那个重载函数?,x1显然是个参数,那是cout调用的 operator<< ?   
  42.     // 解释:cout<<x1 这种调用格式,我摘录的上篇博文中写的很详细了,不过我没有仔细看,今天看了才清楚.  
  43.     /* 
  44.     当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。 
  45.     调用友元函数运算符的格式如下: 
  46.        
  47.         operator <运算符>(<参数1>,<参数2>) 它等价于 <参数1><运算符><参数2> 
  48.         这里参数1 就是 ostream 对象 cout,参数2就是x1 
  49.      */  
  50.     cout = operator<<(cout,x1); //  显示调用,     cout = cout<<x1;   OK  
  51.     x1.operator<<(cout,x1);  //  错! 这样调用不对. 友元函数不是成员函数么?答不是. 因此不用对象.成员的方式  
  52.     /* 
  53.        网上找到一段话,对友元函数的解释,比较好懂: 
  54.        友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数, 
  55.        它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下: 
  56.        friend  类型 函数名(形式参数); 
  57.         
  58.          友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。 
  59.          一个函数可以是多个类的友元函数,只需要在各个类中分别声明。 
  60.          友元函数的调用与一般函数的调用方式和原理一致。          
  61.  
  62.      *   
  63.      */  
  64.       
  65.     /* 
  66.     "<<"  是个什么东东? C++ Prime P6 
  67.     这是个 "输出操作符", 其左边是ostream对象cout,右边是要输出的值 
  68.     它的操作返回输出流本身cout,也就是可以连续写的原因. 
  69.      
  70.     */  
  71.       
  72.     // 既然 cout是 ostream对象,那么可以用 . 的形式 访问ostream的成员函数  
  73.     // 但是 operator<< 在本程序中已经重载了,要按照本程序的形参格式传入参数 ?  
  74.       
  75.        operator<<(cout,x1) ; // ok  
  76.        ostream z(cout);  // ok  
  77.        z<<x1; // 等同 cout<<x1   
  78.          
  79.        operator<<(z,x1);  // ok   
  80.          
  81.        cout<<"=========================="<<endl;  
  82.        z =  operator<<(z,x1);  //ok  
  83. }  
#include <iostream>
#include <string>
using namespace std;

class Student
{
public:
	// 存
	void setname(string s){	name = s;}
	void setage(int y){age = y;	}
	void setaddress(string add){address = add;}    
	// 取
	string getname(){return name;}
	int getage(){return age;}
	string getaddress(){return address;}
	
	Student(string name="",int age=0,string address="")
	{
		this->name = name; this->age = age; this->address = address;      
	}
	~Student(){}
	
    
	//重载 运算符<< : 把 "operator<<" 看作是函数名, 返回类型是 ostream类型的对象引用
	friend ostream& operator<< (ostream &os,Student &st)
	{
		os<<st.name<<"------"<<st.age<<"------"<<st.address<<endl;
		return os;
	}
protected:	
private:
	string name;
	int    age;
	string address;
};

void main()
{ 
	Student x1("刘莉莉",22,"东风路369号"); 
	cout<<x1; 
	//cout<<x1 ---结果OK,问题是这个写法很怪,是谁在调用那个重载函数?,x1显然是个参数,那是cout调用的 operator<< ? 
	// 解释:cout<<x1 这种调用格式,我摘录的上篇博文中写的很详细了,不过我没有仔细看,今天看了才清楚.
	/*
	当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。
	调用友元函数运算符的格式如下:
	  
		operator <运算符>(<参数1>,<参数2>) 它等价于 <参数1><运算符><参数2>
		这里参数1 就是 ostream 对象 cout,参数2就是x1
	 */
	cout = operator<<(cout,x1); //  显示调用,  	cout = cout<<x1;   OK
	x1.operator<<(cout,x1);  //  错! 这样调用不对. 友元函数不是成员函数么?答不是. 因此不用对象.成员的方式
	/*
	   网上找到一段话,对友元函数的解释,比较好懂:
	   友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,
	   它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
	   friend  类型 函数名(形式参数);
	   
		 友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
		 一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
		 友元函数的调用与一般函数的调用方式和原理一致。 		 

	 *	
	 */
	
	/*
	"<<"  是个什么东东? C++ Prime P6
	这是个 "输出操作符", 其左边是ostream对象cout,右边是要输出的值
	它的操作返回输出流本身cout,也就是可以连续写的原因.
	
	*/
	
	// 既然 cout是 ostream对象,那么可以用 . 的形式 访问ostream的成员函数
	// 但是 operator<< 在本程序中已经重载了,要按照本程序的形参格式传入参数 ?
    
	   operator<<(cout,x1) ; // ok
	   ostream z(cout);  // ok
	   z<<x1; // 等同 cout<<x1 
	   
	   operator<<(z,x1);  // ok 
	   
	   cout<<"=========================="<<endl;
	   z =  operator<<(z,x1);  //ok
}


 

 //

 

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. void main()  
  6. {   
  7.   cout.operator <<("csdn"); // 0046E01,是个地址? 为什么不是输出字符串"csdn"?  
  8.   /* 
  9.    cout.operator<<("csdn")这样实际上调用的是ostream重载的成员方法operator<<(...), 
  10.    而ostream并没有针对char*类型的成员重载,所以输出整数。应该使用全局的二元重载operator<<来进行字符串输出 
  11.   ostream& operator<<(ostream& os, char* str); 
  12.   调用方法有二:方法一:操作符调用: cout<<"csdn"; 
  13.   方法二:函数调用:operator<<(cout,"csdn"); 
  14.    */  
  15.   
  16.   //--  
  17.      
  18.   
  19. }  
#include <iostream>
#include <string>
using namespace std;

void main()
{ 
  cout.operator <<("csdn"); // 0046E01,是个地址? 为什么不是输出字符串"csdn"?
  /*
   cout.operator<<("csdn")这样实际上调用的是ostream重载的成员方法operator<<(...),
   而ostream并没有针对char*类型的成员重载,所以输出整数。应该使用全局的二元重载operator<<来进行字符串输出
  ostream& operator<<(ostream& os, char* str);
  调用方法有二:方法一:操作符调用: cout<<"csdn";
  方法二:函数调用:operator<<(cout,"csdn");
   */

  //--
   

}


// ---

格式化输出: 
1. 成员函数: ostream::operator <<, 支持整数(不包括字符类型),浮点数,bool, const void*等。
2。全局函数: operator<<(ostream& os, T const&), 支持字符,字符串和自定义类型
 

  1. #include <iostream>  
  2. #include <iomanip>  
  3. #include <sstream>  
  4. int main()  
  5. {  
  6.     std::istringstream input(" \"Some text.\" ");  
  7.     volatile int n = 42;  
  8.     double f = 3.14;  
  9.     bool b = true;;  
  10.     std::cout << n   // int overload  
  11.               << ' ' // non-member overload  
  12.               << std::boolalpha << b // bool overload  
  13.               << " " // non-member overload  
  14.               << std::fixed << f // double overload  
  15.               << input.rdbuf() // streambuf overload  
  16.               << &n // bool overload  
  17.               << std::endl; // function overload  
  18. }  
#include <iostream>
#include <iomanip>
#include <sstream>
int main()
{
    std::istringstream input(" \"Some text.\" ");
    volatile int n = 42;
    double f = 3.14;
    bool b = true;;
    std::cout << n   // int overload
              << ' ' // non-member overload
              << std::boolalpha << b // bool overload
              << " " // non-member overload
              << std::fixed << f // double overload
              << input.rdbuf() // streambuf overload
              << &n // bool overload
              << std::endl; // function overload
}

0
0
 
 
我的同类文章



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值