Having recently done some development for iPhone, I've come to notice an interesting design pattern used a lot in the iPhone SDK, regarding object mutability.
It seems the typical approach there is to define an immutable class NSFoo
, and then derive from it a mutable descendant NSMutableFoo
. Generally, the NSFoo
class defines data members, getters and read-only operations, and the derived NSMutableFoo
adds on setters and mutating operations.
Being more familiar with C++, I couldn't help but notice that this seems to be a complete opposite to what I'd do when writing the same code in C++. While you certainly could take that approach, it seems to me that a more concise approach is to create a single Foo
class, mark getters and read-only operations as const
functions, and also implement the mutable operations and setters in the same class. You would then end up with a mutable class, but the types Foo const*
, Foo const&
etc all are effectively the immutable equivalent.
I guess my question is, does my take on the situation make sense? I understand why Objective-C does things differently, but are there any advantages to the two-class approach in C++ that I've missed? Or am I missing the point entirely?
Not an overly serious question - more for my own curiosity than anything else.
The mutable is one of the storage class in C++. Mutable data members are that kind of member, which can be changed always. Even if the object is const type. When we need only one member as variable and other as constant, then we can make them mutable.
Mutability means the quality of being changeable. Caterpillars, on their way to becoming butterflies, display a great deal of mutability. An easy way to remember mutability is to think about a word it sounds like, mutant. A mutant is someone who has been changed, irrevocably, so mutability is the ability to change.
Mutable objects are great to use when you need to change the size of the object, example list, dict etc.. Immutables are used when you need to ensure that the object you made will always stay the same. Immutable objects are fundamentally expensive to “change”, because doing so involves creating a copy.
The short answer: yes it is! If you are asking whether it is possible to mutate any memory location in C, the answer is yes.
Objective-C is too dynamic. In C++ const-qualification is enforced at compile-time, and any violations of const-qualification at runtime (such as modifying a const-qualified object through a non-const-qualified pointer) is undefined behaviour.
It is partly the same as the reason why there are no private methods in Objective-C. You are free to send whatever message you want to any object. The runtime dispatch takes an object and a message, and resolves a method implementation to invoke.
if const
qualified objects could only invoke const
qualified methods, it would completely ruin the dynamic nature of Objective-C and Foundation because such a check would need to be done at runtime (first check would determine whether the message being sent resolves to a const-qualified implementation for that specific instance, and another check to determine whether the instance itself was const-qualified). Consider this theoretical example:
NSArray *mutableArray = [[NSArray alloc] init];
NSString *mutableString = @"I am a mutable string";
const NSString *immutableString = @"I am immutable because I am const-qual'd";
[mutableArray addObject:mutableString];
[mutableArray addObject:immutableString]; // what happens?!
// and what happens here (both immutable and mutable strings would respond
// to the same selectors because they are the same class):
[mutableArray makeObjectsPerformSelector:@selector(aMutableOperation)];
Suddenly you lose dynamics. As it is now, mutable and immutable objects can sit together in an immutable or mutable collection.
Having a mutable subclass keeps the dynamic nature of Objective-C and keeps the runtime simple. There was a similar topic a while ago about private methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With