Hacker News new | past | comments | ask | show | jobs | submit login

"Their polymorphic factory isn't returning "different types." They're both returning A."

No, they're not. One is returning a pointer to A, and the other is returning a pointer to B (which just happens to be a subclass of A). It matters, and just because you can do it with a naked pointer doesn't mean that you should. The problem you've described is a code smell.

If I hand you a pointer to B, you (client code) can do everything that is exposed by B. If I hand you a pointer to A, you can only do the set of things exposed by A. And that's a fundamentally different interface guarantee.




There are cases where covariant return types are abused, so it's fine that you treat it as a code smell. However, C++ does make them necessary for several valid patterns. This does include alexgartrell's example, but here's a popular one:

I have a polymorphic type that should be copyable. Because of the limitations of C++ copy constructors and operators, my only option is to expose a virtual method (call it "copy"). The non-smelly semantics we want are such that if you call "copy" on an object, you get an identical copy of the same type. So if you call "copy" on a pointer of type A, you get an A. Call it on a B, you get a B.

The contract itself is polymorphic. It doesn't commit to returning any particular flavor of A.

We can implement this method if we return naked pointers. But if we want to be safe and return a smart pointer, we have to introduce dynamic casting or other worse smells.


"I have a polymorphic type that should be copyable. Because of the limitations of C++ copy constructors and operators, my only option is to expose a virtual method (call it "copy"). The non-smelly semantics we want are such that if you call "copy" on an object, you get an identical copy of the same type."

Well, yeah...because those semantics are just as smelly as the one you described before. What you describe isn't a copy constructor at all, and trying to make a copy constructor do what you want is a dangerous thing. A "constructor" that takes any subclass of class A and returns an instance of that subclass is inherently brittle: add a new subclass of A, and you've got to update the "constructor" to know about the new type. On top of that, your "constructor" has to introspect into the type to determine what to initialize when, and that's slow.

There are easy ways to get the behavior your want (e.g. make a template function that calls the appropriate class' copy constructor, or -- closest to what you want -- make a template copy constructor function on the class itself), but complaining that you can't make a bog-standard copy constructor do polymorphic construction kind of misses the point.

Here's a better discussion of the problem than I have the space to go into here:

http://www.jaggersoft.com/pubs/oload24.html


We're going too deep into this, for alexgartrell's relatively simple claim that covariant return types have a reason for being in the language, and that smart pointers omit that capability.

But just to clarify: no base class implementation is aware of derived classes in the copying case, so your smell doesn't exist. See Scott Meyers' "virtual copy constructor" snippet half way down the page: http://books.google.com/books?id=azvE8V0c-mYC&lpg=PT159&...

You can't do it that neatly without covariant return types. Ergo, you can't do that while returning safe, smart pointers.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: