On 2015-08-03 10:22 PM, Martin Thomson wrote:
On Mon, Aug 3, 2015 at 6:07 PM, Jonas Sicking <jo...@sicking.cc> wrote:
How would you make a factory function like the above fail?


Don't allow for the possibility.  If Foo::Create() is directly
analogous to new Foo(), then it can't fail.  Leave the failing for
later method calls.

No, I think the whole advantage is that you would need to call *one* method for the construction of object, instead of two. In practice, object construction can sometimes be infallible and sometimes cannot due to the things that the object needs to do during construction. Right now, you typically do the following in case the construction is fallible:

nsRefPtr<T> obj = new T(args...);
nsresult rv = obj->Init();
if (NS_WARN_IF(NS_FAILED(rv))) {
  throw error; // whatever
}

This is extremely ugly.

Combine this with the fact that in practice, most of the times the _reason_ why a construction fails is irrelevant, and the caller just uses NS_FAILED() or similar.

Based on the above, I would support adoping a rule along the following lines:

Constructors for refcounted objects must be declared as non-public, and such classes must provide at least two static methods like this:

  static already_AddRefed<T> Create(args...); // never returns null
static already_AddRefed<T> Create(args..., const fallible_t&); // may return null because of an error

The method would return null upon failure. That works very well with nsRefPtr:

nsRefPtr<T> faily = T::Create(args..., fallible);
if (NS_WARN_IF(!faily)) {
  throw error;
}

nsRefPtr<T> robust = T::Create(args...);
// we're done!

Cheers,
Ehsan
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to