无法分配或复制iostream对象?

时间:2012-01-09 08:43:25

标签: c++ iostream initializer-list

iostream和其他流类实际上是类,但是typedef s,对吧?

这是问题所在,我试图在初始化列表中初始化一个istream对象,但不幸的是我收到了一个错误,代码如下:

class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream ais;
};

无法用g ++编译,错误:

synthesized method ‘std::basic_istream<char, std::char_traits<char> >::basic_istream(const std::basic_istream<char, std::char_traits<char> >&)’ first required here 

我搜索了SO,发现了iostream cannot be assigned or copy。但为什么我不能在初始化列表中初始化它?

Cuz我想,初始化列表会调用对象的构造函数/ copy-constructor,对吗?

6 个答案:

答案 0 :(得分:6)

您的代码尝试将一个istream(传递给构造函数的一个)转换为两个istream,即传递给构造函数的aisistreamistream对象表示实际的流本身。只有一个流,并且无法以某种方式将其转换为两个流。

甚至不清楚这意味着什么。如果流上有一些数据,那么先读取哪个数据流得到它?或者他们都得到了吗?如果是这样,谁或什么重复它?

istream就像文件本身。如果不将数据从一个文件复制到另一个文件,则无法将一个文件转换为两个文件。但是,您可以根据需要为同一ais提供尽可能多的引用或指针。您的问题的解决方案可能是{{1}}作为参考。

答案 1 :(得分:4)

您将成员变量声明为:

istream ais;

表示将在初始化列表中调用复制构造函数。这不是特定于初始化列表:您无法在任何地方执行此操作。

您可以将成员变量更改为参考:

istream& ais;

但这意味着您必须确保istream引用的aisA的生命周期内有效。

答案 2 :(得分:3)

  

iostream和其他流类实际上不是类,而是typedef,对吗?

是的,但那不相关。

  

但为什么我不能在初始化列表中初始化它?

因为既不能复制也不能分配。 Ctor init列表并不神奇。要从ais创建is,您需要制作副本,而不能。

答案 3 :(得分:2)

stream对象表示数据流的句柄。复制没有意义。另外,这只是复制流的tge基本部分是不正确的:这将切掉有趣的位(虽然你可以通过使用流缓冲区来获取thr实际上有趣的部分)。

如果您的类中包含流,则要在类中初始化的是对流的引用:

std::istream& ais;

当然,这意味着只要您正在使用它,一些外部需要保持流存活。如果这不是您想要或不需要的,您可以让您的课程举行,例如std::ifstream并将std::string作为构造函数参数:如果字符串非空,则打开相应的文件。否则,您需要将流rdbuf()设置为来自std::cin的<{1}}:

if (name.empty())
    ais.open(name.c_str());
else
    ais.rdbuf(std::cin.rdbuf());

答案 4 :(得分:1)

除了您已经获得的答案之外,您还可以使用您传入的流的 streambuf 初始化ais(根据您的定义)(当然,同样的警告与引用一样适用:您必须确保streambuf在对象被破坏之前保持有效。)

使用底层streambuf进行初始化可能是最接近复制您可以执行的流:虽然两者仍然从同一文件读取并使用相同的缓冲(以及streambuf可能执行的其他处理),但所有格式和错误处理标志是分开的。

要使用streambuf初始化ais,请写下:

class A 
{
public:
  A(std::istream& is = std::cin):
    ais(is.rdbuf())
  {
  }
private:
  std::istream ais;
};

答案 5 :(得分:1)

class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream& ais;
};

请注意,该成员是引用类型。正如你所写,你正在制作一份副本来初始化会员。