2

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

这就是问题所在,我试图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. 但是为什么我不能在初始化列表中对其进行初始化呢?

因为我认为,初始化列表将调用对象的构造函数/复制构造函数,对吗?

4

6 回答 6

7

您的代码尝试将istream传递给构造函数istream的 1 转换为传递给构造函数的 2 和ais。一个istream对象表示该实际流本身。只有一个流,没有办法以某种方式将其变成两个流。

甚至不清楚这意味着什么。如果流上有一些数据,首先读取的流是否会得到它?还是他们都明白?如果是这样,谁或什么复制了它?

Anistream就像一个文件本身。如果不自己将数据从一个文件复制到另一个文件,则无法将一个文件转换为两个文件。但是,您可以拥有任意数量的引用或指针istream。您的问题的解决方案可能ais是参考。

于 2012-01-09T08:48:39.803 回答
5

您将成员变量声明为:

istream ais;

意味着复制构造函数将在初始化列表中被调用。这并不特定于初始化列表:你不能在任何地方这样做。

您可以将成员变量更改为引用:

istream& ais;

但这意味着您必须确保istreamto whichais引用在A.

于 2012-01-09T08:51:38.133 回答
3

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

是的,但这不相关。

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

因为它既不能复制也不能赋值。ctor 初始化列表并不神奇。要从中创建aisis您需要制作副本,而您不能。

于 2012-01-09T08:49:38.653 回答
2

流对象表示数据流的句柄。复制没有意义。此外,仅复制流的 tge 基本部分也不是正确的做法:这将切掉有趣的部分(尽管您可以通过使用流缓冲区获得真正有趣的部分)。

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

std::istream& ais;

当然,这意味着只要您使用它,就需要一些外部设备来保持流处于活动状态。如果这不是您想要或需要的,您可以让您的类持有例如 anstd::ifstream并将 astd::string作为构造函数参数:如果字符串非空,您将打开相应的文件。否则,您会将流设置rdbuf()为来自std::cin

if (name.empty())
    ais.open(name.c_str());
else
    ais.rdbuf(std::cin.rdbuf());
于 2012-01-09T09:02:10.797 回答
1

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

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

要使用 streambuf 进行初始化ais,请编写:

class A 
{
public:
  A(std::istream& is = std::cin):
    ais(is.rdbuf())
  {
  }
private:
  std::istream ais;
};
于 2012-01-09T08:59:39.020 回答
1
class A 
{
    public:
        A(istream &is=cin): ais(is)
        {}

    private:
        istream& ais;
};

请注意,成员是引用类型。正如你所写的那样,你正在制作一个副本来初始化成员。

于 2012-01-09T09:51:29.143 回答