cin/cout并不是C++的关键字,而是对象。
C++的<iostrem>中,有一个istream类和一个ostream类,而cin就是istream类的对象,cout就是ostream类的对象。
流符号是怎样实现的呢?
C++支持重载运算符,而流符号(<<、>>)就是重载了左移和右移运算符的结果。i/ostream类有多个左移/右移运算符,用来输入/输出不同类型的变量。
endl、flush这样的效果是怎样实现的呢?我想,应该是用函数指针的方式实现的。即把左移、右移的参数定为函数指针,而endl、flush等就是你传入的函数。
而setprecision(n)带括号的形式是怎么来的呢?我想到了一种方法。(注意可能实际不是,但是可以用这种方法实现)可以把setprecision函数的返回类型设为一个结构体,然后在这个结构体中重载()运算符,这样就变成了一个仿函数,就可以在输入输出流中使用带括号的函数了。
另外,重载输入输出流时要注意设置为友元函数,第一个参数为i/ostream,第二个参数如果是输入,加上&引用;如果是输出,不要加引用,因为你可能会输出一些临时值,比如a+b的结果。
最后附上我用以上分析制造出来的my_i/ostream(输入输出采用scanf/printf函数):
//myio.h
#ifndef MYIO_H
#define MYIO_H
#include<cstdio>
#include<cstring>
#include<string> //one of I/O type
#ifndef I_CSTR_MAX_SIZE
#define I_CSTR_MAX_SIZE 1003
#endif
using std::scanf;
using std::printf;
using std::freopen;
using std::fclose;
using std::string;
void flush(){}
int endl(){}
struct set_precision_class{
struct setp_num{
int number;
};
setp_num operator () (int numbers){
setp_num ans={numbers};
return ans;
}
}set_precision;
struct oct_class{
struct oct_type{
unsigned int number;
};
oct_type operator () (int numbers){
oct_type ans={numbers};
return ans;
}
}octal;
struct hex_class{
struct hex_type{
unsigned int number;
};
hex_type operator () (int numbers){
hex_type ans={numbers};
return ans;
}
}hexal;
struct f_open_class{
struct open_type{
char* name;
};
open_type operator () (const char* fname){
open_type ans={const_cast<char*>(fname)};
return ans;
}
}f_open;
struct float_format_class{
struct format_type{
char* format;
};
format_type operator () (const char* float_format_cst_cstr){
format_type ans={const_cast<char*>(float_format_cst_cstr)};
return ans;
}
}float_format;
char f_close(){}
class my_istream{
public:
my_istream operator >> (short &short_var){
scanf("%d",&short_var);
return *this;
}
my_istream operator >> (unsigned short &unsigned_short_var){
scanf("%u",&unsigned_short_var);
return *this;
}
my_istream operator >> (int &int_var){
scanf("%d",&int_var);
return *this;
}
my_istream operator >> (unsigned int &unsigned_int_var){
scanf("%u",&unsigned_int_var);
return *this;
}
my_istream operator >> (long &long_var){
scanf("%ld",&long_var);
return *this;
}
my_istream operator >> (unsigned long &unsigned_long_var){
scanf("%lu",&unsigned_long_var);
return *this;
}
my_istream operator >> (long long &long_long_var){
scanf("%lld",&long_long_var);
return *this;
}
my_istream operator >> (unsigned long long &unsigned_long_long_var){
scanf("%llu",&unsigned_long_long_var);
return *this;
}
my_istream operator >> (float &float_var){
scanf("%f",&float_var);
return *this;
}
my_istream operator >> (double &double_var){
scanf("%lf",&double_var);
return *this;
}
my_istream operator >> (long double &long_double_var){
scanf("%llf",&long_double_var);
return *this;
}
my_istream operator >> (char &char_var){
scanf("%c",&char_var);
return *this;
}
my_istream operator >> (unsigned char &unsigned_char_var){
scanf("%c",&unsigned_char_var);
return *this;
}
my_istream operator >> (char* &cstring_var){
cstring_var=new char[I_CSTR_MAX_SIZE];
scanf("%s",cstring_var);
return *this;
}
my_istream get_cstr(char* &cstring_var,int cstr_size=I_CSTR_MAX_SIZE){
cstring_var=new char[cstr_size];
scanf("%s",cstring_var);
return *this;
}
my_istream operator >> (string &string_var){
char* temp_cstr=new char[I_CSTR_MAX_SIZE];
scanf("%s",temp_cstr);
string_var=temp_cstr;
return *this;
}
my_istream get_cppstr(string &string_var,int str_size=I_CSTR_MAX_SIZE){
char* temp_cstr=new char[str_size];
scanf("%s",temp_cstr);
string_var=temp_cstr;
return *this;
}
my_istream operator >> (void (*i_flush)()){
fflush(stdin);
return *this;
}
my_istream operator >> (f_open_class::open_type file_name){
freopen(file_name.name,"r",stdin);
return *this;
}
my_istream operator >> (char (*i_fclose)()){
fclose(stdin);
return *this;
}
}myin;
class my_ostream{
private:
char fixed_setprecision[5];
char cstr_float_format[2];
public:
my_ostream(){
strcpy(fixed_setprecision,"");
strcpy(cstr_float_format,"g");
}
my_ostream operator << (short short_var){
printf("%d",short_var);
return *this;
}
my_ostream operator << (unsigned short unsigned_short_var){
printf("%u",unsigned_short_var);
return *this;
}
my_ostream operator << (int int_var){
printf("%d",int_var);
return *this;
}
my_ostream operator << (unsigned int unsigned_int_var){
printf("%u",unsigned_int_var);
return *this;
}
my_ostream operator << (long long_var){
printf("%ld",long_var);
return *this;
}
my_ostream operator << (unsigned long unsigned_long_var){
printf("%lu",unsigned_long_var);
return *this;
}
my_ostream operator << (long long long_long_var){
printf("%lld",long_long_var);
return *this;
}
my_ostream operator << (unsigned long long unsigned_long_long_var){
printf("%llu",unsigned_long_long_var);
return *this;
}
my_ostream operator << (float float_var){
char temp_setp[10]="%";
strcat(temp_setp,fixed_setprecision);
printf(strcat(temp_setp,cstr_float_format),float_var);
return *this;
}
my_ostream operator << (double double_var){
char temp_setp[10]="%";
strcat(temp_setp,fixed_setprecision);
printf(strcat(temp_setp,cstr_float_format),double_var);
return *this;
}
my_ostream operator << (long double long_double_var){
char temp_setp[10]="%";
strcat(temp_setp,fixed_setprecision);
printf(strcat(temp_setp,strcat(const_cast<char*>("L"),cstr_float_format)),long_double_var);
return *this;
}
my_ostream operator << (char char_var){
printf("%c",char_var);
return *this;
}
my_ostream operator << (const char* cstring_var){
printf("%s",cstring_var);
return *this;
}
my_ostream operator << (string string_var){
printf("%s",string_var.c_str());
return *this;
}
// format
my_ostream operator << (void (*o_flush)()){
fflush(stdout);
return *this;
}
my_ostream operator << (int (*o_endl)()){
printf("\n");
fflush(stdout);
return *this;
}
my_ostream operator << (set_precision_class::setp_num setp_number){
char tempcstr[5]=".";
char str_numbers[3];
sprintf(str_numbers,"%d",setp_number.number);
strcat(tempcstr,str_numbers);
strcpy(fixed_setprecision,tempcstr);
return *this;
}
my_ostream operator << (oct_class::oct_type dec_number){
printf("%o",dec_number.number);
return *this;
}
my_ostream operator << (hex_class::hex_type dec_number){
printf("%x",dec_number.number);
return *this;
}
my_ostream operator << (f_open_class::open_type file_name){
freopen(file_name.name,"w",stdout);
return *this;
}
my_ostream operator << (char (*o_fclose)()){
fclose(stdout);
return *this;
}
my_ostream operator << (float_format_class::format_type format_str){
strcpy(cstr_float_format,format_str.format);
return *this;
}
}myout;
class my_iostream:public my_istream,public my_ostream{}myio;
#endif
我在倒数第二行添加了一个混合功能类,可以这样使用:
int a;
myio>>a;
myio<<a;
就不用换名称了。但是注意,以下做法是不成立的:
int a;
myio>>a<<a;
因为>>返回的是my_istream类对象,而my_istream类是没有<<这个成员函数的。
友情提示:myio虽然用的是scanf/printf,但是在大多数情况下仍然比cin/cout慢。这让我很困惑。大家能解释一下原因吗?
另外,我还编写了一个快速输入输出类,其中qin的速度比scanf和cin都快很多,但是功能比较少。