Boolean Parameters
In this case, we can improve eighty-seven separate constructors with one simple refactoring that takes almost no time, while leaving a clear indication that those Legacy strings could bear attention when time allows.
4 Comments RSS · Twitter
It's been so long since I dabbled in C++, I can't remember how 1-1 constructors are with specific classes. In Objective-C, instead of subclassing for the legacy behavior, I would probably put a convenience init wrapper in a named legacy-support method. -[MyClass initWithMacRomanString:] documents the legacy behavior just as well without requiring a stinky subclass that provides no differentiated functionality.
In C++ one can use default arguments and an enumeration instead of a boolean:
enum class encoding { UTF8, MacRoman };
…
my_string (char const* str, encoding enc = encoding::UTF8);
Now you only need to add encoding::MacRoman for the legacy case. In this particular case though, it might be better to introduce a wrapper function that converts from MacRoman to UTF-8 and then wrap the constructor argument, so that the string class will always get UTF-8 strings.
I agree that this refactoring is more idiomatic for c++ than for objective C. Still, there's virtue alike in e single-argument constructor and in the specific subclass for the unusual case. Often, that will make it easier someday to eliminate the subclass entirely.
I'm not convinced the subclass is a code smell. Sure, newbies use inheritance too much, and so we're all conscious of that. But even for c++, which is VERY suspicious of subclasses, this is up to snuff; MacRomanUnicodeString *isa* UnifodeString.
On the other hand, I'm becoming quite leary of default argument, especially in two-argument constructors where the default argument enables one-argument construction.