【问题标题】:C++ std::ifstream in constructor problem构造函数中的 C++ std::ifstream 问题
【发布时间】:2010-10-02 21:33:10
【问题描述】:

这段代码有问题:

#include <fstream>

struct A
{   
    A(std::ifstream input)
    {
        //some actions
    }
};

int main()
{
    std::ifstream input("somefile.xxx");

    while (input.good())
    {
        A(input);
    }

    return 0;
}

G++ 输出给我这个:

$ g++ file.cpp
file.cpp: In function `int main()':
file.cpp:17: error: no matching function for call to `A::A()'
file.cpp:4: note: candidates are: A::A(const A&)
file.cpp:6: note:                 A::A(std::ifstream)

改成这个后编译(但这并不能解决问题):

#include <fstream>

struct A
{   
    A(int a)
    {
        //some actions
    }
};

int main()
{
    std::ifstream input("dane.dat");

    while (input.good())
    {
        A(5);
    }

    return 0;
}

谁能解释我出了什么问题以及如何解决它?谢谢。

【问题讨论】:

    标签: c++ constructor g++ ifstream


    【解决方案1】:

    两个错误:

    • ifstream 不可复制(将构造函数参数更改为引用)。
    • A(input); 等价于 A input;。因此编译器尝试调用默认构造函数。用括号包裹它(A(input));。或者直接给它起个名字A a(input);

    另外,为此使用函数有什么问题?似乎只使用了类的构造函数,您似乎滥用了它作为返回void 的函数。

    【讨论】:

    • 不是A(input)在构造一个临时的A对象吗?
    • @Martin input 周围的括号是声明符中使用的绑定括号,例如它们出现在 void (*p)(); 周围的 *p 中。 input 周围的那些是多余的。这是人们在vector&lt;int&gt; p(istream_iterator&lt;int&gt;(cin), ...); 中偶尔会遇到的情况,其中在cin 周围指定了多余的括号。
    • 我忘了提到我用引用尝试过那个东西。 (A(input)) 是错误,谢谢。
    【解决方案2】:

    ifstream 没有复制构造函数。 A(std::ifstream input) 表示“A 的构造函数采用ifstream 按值。”这需要编译器制作流的副本以传递给构造函数,因为不存在这样的操作,所以它不能这样做。

    您需要通过引用传递流(意思是“使用相同的流对象,而不是它的副本。”)因此将构造函数签名更改为A(std::ifstream&amp; input)。请注意与号,表示“引用”,对于函数参数,表示“按引用而不是按值传递此参数。


    风格说明:while 循环体A(input); 构造了一个A 类型的结构,然后在while 循环循环时几乎立即销毁。你确定这是你想做的吗?如果这段代码是完整的,那么让它成为一个函数或A 的成员函数会更有意义,它在循环之外构造:

    static void process(std::istream& stream)
    {
        // some actions
        // note stream is declared as std::istream&; this lets you pass
        // streams that are *not* file-based, if you need to
    }
    
    int main()
    {
        std::ifstream input("somefile.xxx");
    
        while (input.good())
        {
            process(input);
        }
    
        return 0;
    }
    

    struct A
    {   
        A()
        {
            // default constructor for struct A
        }
    
        void process(std::istream& stream)
        {
            // some actions
        }
    };
    
    int main()
    {
        std::ifstream input("somefile.xxx");
    
        A something;
        while (input.good())
        {
            something.process(input);
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      流是不可复制的。

      所以你需要通过引用传递。

      struct A
      {   
          A(std::ifstream& input)
                       ^^^^^
          {
              //some actions
          }
      };
      

      【讨论】:

        猜你喜欢
        • 2016-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多