?前面在调用函数提到为了将信息打印到ofil中,前面提到的办法是
ofstream ofil("text_out1");void bubble_sort(vector<int>? vec){
}
在file scope中定义ofil,这是一个不受欢迎的举动。这样比较难在其他环境重用
一般的程序编写法则是,以“参数传递”作为函数间的沟通方式,比直接将对象定义于file scope更合适。
应该这样修改? void swap(int &val,int &val,ofstream ?&ofil);
void bubble_sort(vector<int> &vec,ofstream &ofil);
例如
void swap(int &val1,int &val2,ofstream &ofil){
?? ?ofil<<"swap("<<val1
?? ?<<","<<val2<<")\n";
?? ?
?? ?int temp=val1;
?? ?val1=val2;
?? ?val2=temp;
?? ?
?? ?ofil<<"after swap(): val1 "<<val1
?? ?<<"val2: "<<val2<<"\n";
}
?void bubble_sort(vector<int> &vec,ofstream &ofil)
?{
??? ?for(int ix=0;ix<vec.size();++ix)
??? ??? ?for(int jx=ix+1;jx<vec.size();++jx)
??? ??? ??? ?if(vec[ix]>vec[jx]){
??? ??? ??? ?ofil<<"about to call swap"
??? ??? ??? ??? ?<<"ix: "<<ix<<"jx: "<<jx<<"\t"
??? ??? ??? ??? ?<<"swapping: "<<vec[ix]
??? ??? ??? ??? ?<<"with"<<vec[jx]<<endl;
??? ??? ??? ?swap(vec[ix],vec[jx],ofil);
?? ??? ??? ? }
?}
#include <iostream>
#include <vector>
#include<fstream>
using namespace std;
void display(vector<int> vec,ostream &os=cout)
{
for(int ix=0;ix<vec.size();++ix)
os<<vec[ix]<<" ";
os<<endl;
}
// void swap(int val1,int val2)
// {
// int temp=val1;
// val1=val2;
// val2=temp;
// }
//ofstream ofil("text_out1");
void swap(int &val1,int &val2,ofstream &ofil){
ofil<<"swap("<<val1
<<","<<val2<<")\n";
int temp=val1;
val1=val2;
val2=temp;
ofil<<"after swap(): val1 "<<val1
<<"val2: "<<val2<<"\n";
}
void bubble_sort(vector<int> &vec,ofstream &ofil)
{
for(int ix=0;ix<vec.size();++ix)
for(int jx=ix+1;jx<vec.size();++jx)
if(vec[ix]>vec[jx]){
ofil<<"about to call swap"
<<"ix: "<<ix<<"jx: "<<jx<<"\t"
<<"swapping: "<<vec[ix]
<<"with"<<vec[jx]<<endl;
swap(vec[ix],vec[jx],ofil);
}
}
// void bubble_sort(vector<int> vec)
// {
// for(int ix=0;ix<vec.size();++ix)
// for(int jx=ix+1;jx<vec.size();++jx)
// if(vec[ix]>vec[jx])
// swap(vec[ix],vec[jx]);
// }
int main(){
int ia[8]={8,34,3,13,1,21,5,2};
vector<int> vec(ia,ia+8);
cout<<"vector before sort:";
display(vec);
ofstream ofil("dat.txt");
bubble_sort(vec,ofil);
cout<<"vector after sort:";
display(vec,ofil);
}
运行是可以成功的
?
但是存在两个问题
1.每次调用bubble_sort()都必须传入一个ofstream对象2而且用户无法关闭我们所产生的信息(我个人对第二个是这么理解的,每次都会在文件写)
如下所示,必须两个参数,一个就会报错
?然后我们思考,我们希望用户不但不必指定输出用的stream,而且有能力把输出信息关闭。默认情形下我们不想产生这些信息,但是我们又希望让那些想看到这些信息的用户可以产生他们,甚至指定其输出文件
我们考虑让部分参数设定默认值? ?代码如下
#include <iostream>
#include <vector>
#include<fstream>
using namespace std;
void display(vector<int> vec,ostream &os=cout)
{
for(int ix=0;ix<vec.size();++ix)
os<<vec[ix]<<" ";
os<<endl;
}
// void swap(int val1,int val2)
// {
// int temp=val1;
// val1=val2;
// val2=temp;
// }
//ofstream ofil("text_out1");
void swap(int &val1,int &val2,ofstream *ofil=0){
(*ofil)<<"swap("<<val1
<<","<<val2<<")\n";
int temp=val1;
val1=val2;
val2=temp;
(*ofil)<<"after swap(): val1 "<<val1
<<"val2: "<<val2<<"\n";
}
void bubble_sort(vector<int> &vec,ofstream *ofil=0)
{
for(int ix=0;ix<vec.size();++ix)
for(int jx=ix+1;jx<vec.size();++jx)
if(vec[ix]>vec[jx]){
(*ofil)<<"about to call swap"
<<"ix: "<<ix<<"jx: "<<jx<<"\t"
<<"swapping: "<<vec[ix]
<<"with"<<vec[jx]<<endl;
swap(vec[ix],vec[jx],ofil);
}
}
// void bubble_sort(vector<int> vec)
// {
// for(int ix=0;ix<vec.size();++ix)
// for(int jx=ix+1;jx<vec.size();++jx)
// if(vec[ix]>vec[jx])
// swap(vec[ix],vec[jx]);
// }
int main(){
int ia[8]={8,34,3,13,1,21,5,2};
vector<int> vec(ia,ia+8);
cout<<"vector before sort:";
display(vec);
ofstream ofil("dat.txt");
bubble_sort(vec,&ofil);
cout<<"vector after sort:";
display(vec,ofil);
}
将第二个参数声明为ofstream对象的一个pointer而非reference。我们必须做这样的改变,才可以为它设定默认值0,表示并未指向任何ofstream对象。reference不同于pointer,无法被设置为0。因此,reference一定要代表某个对象
然后有了这样的改变,当用户以单一参数调用bubble_sort()时,不会产生任何调试信息。如果调用时带有第二个参数,指向某个ofstream对象,那么这个函数便会产生调试信息。
?
int main(){
int ia[8]={8,34,3,13,1,21,5,2};
vector<int> vec(ia,ia+8);
//以下就像调用bubble_sort(vec,0);一样
//不会产生任何调试信息
bubble_sort(vec);
display(vec);
//ok,这样会产生调试信息
ofstream ofil("dat.txt");
bubble_sort(vec,&ofil);
display(vec,ofil);
修改display后输在文件上
void display(vector<int> vec,ostream &os=cout)
{
?? ?for(int ix=0;ix<vec.size();++ix)
?? ??? ?os<<vec[ix]<<" ";
?? ?os<<endl;?
?}?
效果如下?
这里做个小延申
1? ? ? ? 默认值的解析操作由最右边开始进行。如果我们为某个参数提供了默认值,那么这一参数右侧的所有参数都必须也具有默认参数值才行。
2? ? ? ? 默认值只能指定一次,可以在函数声明处,也可以在函数定义处,但切记不能在两个地方都指定。最好在函数声明处。头文件具有可见性。