引用传值的一个问题。谢谢。

时间:2008-08-27 23:01:35   来源:论坛整理  作者:  编辑:chinaitzhe
RT.. 测试书上例子时遇到的一个问题。

有这样一个方法。
void file_it(ostream & os)

这样二种调用方式:
1:
ofstream fout;
file_it(fout);

2: file_it(std::cin);

请问为什么file_it方法参数一定要用引用? 我改成这样void file_it(ostream os)编译不能通过。 谢谢。
网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





//传引用

//不产生临时副本,直接作用于参数对象



//两种都是可以的,如下:



#include <iostream>

#include <fstream>

using namespace std;



void file_it(ostream os)

{

    

}

void main() 

{

    ofstream fout; 

    file_it(fout);     

} 



#include <iostream>

#include <fstream>

using namespace std;



void file_it(ostream &os)

{

    

}

void main() 

{

    ofstream fout; 

    file_it(fout);     

} 




网友回复:这是原代码:

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





#include <iostream>

#include <fstream>

#include <cstdlib>



using namespace std;



void file_it(ostream& os, double fo, const double fe[], int n);



const int LIMIT = 5;



int main()

{

    ofstream fout;

    const char* fn = "ep-data.txt";

    fout.open(fn);

    if(!fout.is_open())

    {

        cout << "Can't open " << fn << ". Bye.\n";

        exit(EXIT_FAILURE);

    }



    double objective;

    cout << "Enter the focal length of your telescope objective in mm: ";

    cin >> objective;

    double eps[LIMIT];

    cout << "Enter the focal lengths, in mm, of " << LIMIT << " eyepieces:\n";

    for(int i = 0; i < LIMIT; i  )

    {

        cout << "Eyepiece #" << i   1 << ": ";

        cin >> eps[i];

    }



    file_it(fout, objective, eps, LIMIT);

    file_it(cout, objective, eps, LIMIT);

}



void file_it(ostream& os, double fo, const double fe[], int n)

{

    ios_base::fmtflags initial;

    initial = os.setf(ios_base::fixed); 

    os.precision(0);

    os << "Focal length of objective: " << fo << " mm\n";

    os.setf(ios::showpoint);

    os.precision(1);

    os.width(12);

    os << "f eyepiece";

    os.width(15);

    os << "magnification" << endl;

    for(int i = 0; i < n; i  )

    {

        os.width(12);

        os << fe[i];

        os.width(15);

        os << int(fo / fe[i]   0.5) << endl;

    }

    os.setf(initial);  

}





我把void file_it(ostream& os, double fo, const double fe[], int n) 换成 void file_it(ostream os, double fo, const double fe[], int n) 就不行。

错误提示:

------ 已启动生成: 项目: bookTest, 配置: Debug Win32 ------
正在编译...
test.cpp
e:\development\vc 2008\include\ostream(584) : error C2248: “std::basic_ios <_Elem,_Traits>::basic_ios”: 无法访问 private 成员(在“std::basic_ios <_Elem,_Traits>”类中声明)


请问是什么原因? 谢谢。
网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





//改成这样:

#include <iostream>

#include <fstream>

#include <cstdlib>



using namespace std;



void file_it(ostream os, double fo, const double fe[], int n);//这里也得改下,要细心



const int LIMIT = 5;



int main()

{

    ofstream fout;

    const char* fn = "ep-data.txt";

    fout.open(fn);

    if(!fout.is_open())

    {

        cout << "Can't open " << fn << ". Bye.\n";

        exit(EXIT_FAILURE);

    }

    

    double objective;

    cout << "Enter the focal length of your telescope objective in mm: ";

    cin >> objective;

    double eps[LIMIT];

    cout << "Enter the focal lengths, in mm, of " << LIMIT << " eyepieces:\n";

    for(int i = 0; i < LIMIT; i  )

    {

        cout << "Eyepiece #" << i   1 << ": ";

        cin >> eps[i];

    }

    

    file_it(fout, objective, eps, LIMIT);

    file_it(cout, objective, eps, LIMIT);

}



void file_it(ostream os, double fo, const double fe[], int n)

{

    ios_base::fmtflags initial;

    initial = os.setf(ios_base::fixed); 

    os.precision(0);

    os << "Focal length of objective: " << fo << " mm\n";

    os.setf(ios::showpoint);

    os.precision(1);

    os.width(12);

    os << "f eyepiece";

    os.width(15);

    os << "magnification" << endl;

    for(int i = 0; i < n; i  )

    {

        os.width(12);

        os << fe[i];

        os.width(15);

        os << int(fo / fe[i]   0.5) << endl;

    }

    os.setf(initial);  

}






网友回复:上面头声明我也是改过的。
网友回复:
引用 4 楼 Qlin 的回复:
上面头声明我也是改过的。

我3楼贴的是正确的,你试了吗

网友回复:试了,报同二楼一样的错。
网友回复:
引用 6 楼 Qlin 的回复:
试了,报同二楼一样的错。

我在VC6下能运行:

下面是运行:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/





Enter the focal length of your telescope objective in mm: gggg

Enter the focal lengths, in mm, of 5 eyepieces:

Eyepiece #1: Eyepiece #2: Eyepiece #3: Eyepiece #4: Eyepiece #5: Focal len

 objective: -9255963134931783100000000000000000000000000000000000000000000

  f eyepiece  magnification

-92559631349317831000000000000000000000000000000000000000000000.0



-92559631349317831000000000000000000000000000000000000000000000.0



-92559631349317831000000000000000000000000000000000000000000000.0



-92559631349317831000000000000000000000000000000000000000000000.0



-92559631349317831000000000000000000000000000000000000000000000.0



Press any key to continue






网友回复:该回复于2008-08-26 16:20:46被版主删除
网友回复:流对象如istream,ostream是不可复制的一种对象,参数为值的话就会产生副本,即会自动进行复制
而流对象无法复制,所以出错,参数为引用的话就是对参数直接进行操作(别名),所以可以。
网友回复:
引用 9 楼 taojian_hhu 的回复:
流对象如istream,ostream是不可复制的一种对象,参数为值的话就会产生副本,即会自动进行复制
而流对象无法复制,所以出错,参数为引用的话就是对参数直接进行操作(别名),所以可以。

网友回复:
引用 6 楼 Qlin 的回复:
试了,报同二楼一样的错。


用的啥编译器?
网友回复:在VC6中,ostream基类basic_ios <char,char_traits <char>>的拷贝构造函数:
basic_ios(const _Myt& _R)
{init(0), *this = _R; }
是public属性的,所以可以编译通过.

在VS2005下时:
private:
__CLR_OR_THIS_CALL basic_ios(const _Myt&);

所以编译无法通过.
以上
网友回复:file_it(ostream os)
这个调用时,主调函数会执行ostream的拷贝构造函数,接着ostream会执行其基类的拷贝构造函数.
因此会出现LZ所说问题.

而file_it(ostream& os)的主调函数直接把os地址入栈,并不会产生以上动作、故可以.
网友回复:纠正刚才一点错误、ostream并没有定义其拷贝构造函数、
file_it(ostream os)
这个调用时,主调函数会执行ostream的普通构造函数,接着ostream会执行其基类的拷贝构造函数.
关键字:问题,
上一篇:模板与迭代器

相关文章

文章评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面