C++ 在构造函数中初始化std::istream中的const类数据成员
我想从std::istream:C++ 在构造函数中初始化std::istream中的const类数据成员,c++,c++11,constructor,constants,C++,C++11,Constructor,Constants,我想从std::istream: class MyClass { private: const int dataMember; public: MyClass(std::istream& is) { /* read into datamember } } 我想使用istream实例的>>运算符来填写我的dataMember,但我的dataMember是const。C++有什么方法可以做到这一点吗?< /p> 当然,只要把它包在一个函数中: MyClass(std::istr
class MyClass {
private: const int dataMember;
public: MyClass(std::istream& is) { /* read into datamember }
}
我想使用istream实例的>>运算符来填写我的dataMember,但我的dataMember是const。C++有什么方法可以做到这一点吗?< /p> 当然,只要把它包在一个函数中:
MyClass(std::istream& is) : dataMember{readInt(is)}{}
您可以通过从助手函数中抛出来处理输入错误
如果您确实想在没有助手函数的情况下执行此操作,可以使用istream\u迭代器强制执行此操作:
MyClass(std::istream& is) : dataMember{*std::istream_iterator<int>(is)}{}
MyClass(std::istream&is):数据成员{*std::istream\u迭代器(is)}{
然而,这将导致一些古怪的错误处理。错误处理可以通过完成,但是调用方必须记住启用它们。否则,失败的读取操作将调用UB
出于错误处理的原因,我更喜欢helper函数。(尤其是我花了三次迭代才把它做好,我提倡在一次迭代中使用UB。)当然,只需将它包装在函数中:
MyClass(std::istream& is) : dataMember{readInt(is)}{}
您可以通过从助手函数中抛出来处理输入错误
如果您确实想在没有助手函数的情况下执行此操作,可以使用istream\u迭代器强制执行此操作:
MyClass(std::istream& is) : dataMember{*std::istream_iterator<int>(is)}{}
MyClass(std::istream&is):数据成员{*std::istream\u迭代器(is)}{
然而,这将导致一些古怪的错误处理。错误处理可以通过完成,但是调用方必须记住启用它们。否则,失败的读取操作将调用UB
出于错误处理的原因,我更喜欢helper函数。(特别是我花了三次迭代才把它弄对,我在一次迭代中就提出了UB。)您可以创建一个函数,该函数接收流并返回一个对象。此函数从流中提取数据并将其放入构造函数中
static MyClass fromIStream(std::istream& is) {
int datamember;
is >> datamember;
return MyClass(datamember);
}
您可以创建一个接收流并返回对象的函数。此函数从流中提取数据并将其放入构造函数中
static MyClass fromIStream(std::istream& is) {
int datamember;
is >> datamember;
return MyClass(datamember);
}
是的,有没有不引入辅助函数的方法?我通常不喜欢用很多小函数来弥补语言的缺陷。是的,有没有办法不引入辅助函数呢?我通常不喜欢用很多小功能来弥补语言缺陷。正如其他人所回答的,这是可能的。但是,我认为数据成员不应该是const
。它已经是私有的,您可以通过类API强制MyClass
的用户使用它。另外,const
将破坏复制语义(例如,复制赋值将不起作用)。例如,在较新的语言(如Scala)中,您可以将类数据成员定义为val,即使从类成员函数中也无法更改它们。因此,一旦它被创造出来,它就永远不会被改变。这在并发性很重要的情况下会有很大帮助。正如其他人所回答的,这是可能的。但是,我认为数据成员不应该是const
。它已经是私有的,您可以通过类API强制MyClass
的用户使用它。另外,const
将破坏复制语义(例如,复制赋值将不起作用)。例如,在较新的语言(如Scala)中,您可以将类数据成员定义为val,即使从类成员函数中也无法更改它们。因此,一旦它被创造出来,它就永远不会被改变。在并发性很重要的环境中,这会有很大帮助。