J
Jason Heyes
I want to allow objects of my class to be read from an input stream. I am
having trouble with the implementation. Here are the different approaches I
have tried:
// Version 1.0 - Default constructors
class MyClass
{
Foo foo; // foo and bar require default constructors
Bar bar;
public:
// default constructor for MyClass
MyClass() // foo and bar are default initialised
{
}
std::istream &extract(std::istream &is)
{
if (!(is >> foo))
return is;
if (!(is >> bar))
return is;
return is;
}
};
std::istream &operator>>(std::istream &is, MyClass &object)
{
return is >> object;
}
// Version 2.0 - std::istream constructor argument, default constructors and
exceptions
class MyClass
{
Foo foo; // foo and bar require default constructors
Bar bar;
public:
MyClass(std::istream &is) // foo and bar are default initialised
{
if (!(is >> foo))
throw MyException;
if (!(is >> bar))
throw MyException;
}
};
// Version 3.0 - Shared pointers
class MyClass
{
Foo foo;
Bar bar;
public:
MyClass(Foo foo_, Bar bar_) : foo(foo_), bar(bar_) { }
};
std::istream &operator>>(std::istream &is, SharedPtr<MyClass> &object_ptr)
{
SharedPtr<Foo> foo_ptr;
if (!(is >> foo_ptr))
return is;
Foo foo = *foo_ptr;
SharedPtr<Bar> bar_ptr;
if (!(is >> bar_ptr))
return is;
Bar bar = *bar_ptr;
object_ptr = new MyClass(foo, bar);
return is;
}
// Version 4.0 - Static read methods and exceptions
class MyClass
{
Foo foo
Bar bar;
public:
MyClass(Foo foo_, Bar bar_) : foo(foo_), bar(bar_) { }
static MyClass read(std::istream &is);
};
MyClass MyClass::read(std::istream &is)
{
try {
Foo foo = Foo::read(is);
Bar bar = Bar::read(is);
return MyClass(foo, bar);
} catch (FooException e) {
throw MyException(e.get_desc());
} catch (BarException e) {
throw MyException(e.get_desc());
}
}
The third version is the only approach that does not involve default
constructors or exceptions. How else can I write my class to allow it's
objects to be read from a stream? Thanks.
having trouble with the implementation. Here are the different approaches I
have tried:
// Version 1.0 - Default constructors
class MyClass
{
Foo foo; // foo and bar require default constructors
Bar bar;
public:
// default constructor for MyClass
MyClass() // foo and bar are default initialised
{
}
std::istream &extract(std::istream &is)
{
if (!(is >> foo))
return is;
if (!(is >> bar))
return is;
return is;
}
};
std::istream &operator>>(std::istream &is, MyClass &object)
{
return is >> object;
}
// Version 2.0 - std::istream constructor argument, default constructors and
exceptions
class MyClass
{
Foo foo; // foo and bar require default constructors
Bar bar;
public:
MyClass(std::istream &is) // foo and bar are default initialised
{
if (!(is >> foo))
throw MyException;
if (!(is >> bar))
throw MyException;
}
};
// Version 3.0 - Shared pointers
class MyClass
{
Foo foo;
Bar bar;
public:
MyClass(Foo foo_, Bar bar_) : foo(foo_), bar(bar_) { }
};
std::istream &operator>>(std::istream &is, SharedPtr<MyClass> &object_ptr)
{
SharedPtr<Foo> foo_ptr;
if (!(is >> foo_ptr))
return is;
Foo foo = *foo_ptr;
SharedPtr<Bar> bar_ptr;
if (!(is >> bar_ptr))
return is;
Bar bar = *bar_ptr;
object_ptr = new MyClass(foo, bar);
return is;
}
// Version 4.0 - Static read methods and exceptions
class MyClass
{
Foo foo
Bar bar;
public:
MyClass(Foo foo_, Bar bar_) : foo(foo_), bar(bar_) { }
static MyClass read(std::istream &is);
};
MyClass MyClass::read(std::istream &is)
{
try {
Foo foo = Foo::read(is);
Bar bar = Bar::read(is);
return MyClass(foo, bar);
} catch (FooException e) {
throw MyException(e.get_desc());
} catch (BarException e) {
throw MyException(e.get_desc());
}
}
The third version is the only approach that does not involve default
constructors or exceptions. How else can I write my class to allow it's
objects to be read from a stream? Thanks.