最近为 iPhone 做了一些开发,我开始注意到一个有趣的设计模式在 iPhone SDK 中大量使用,关于对象可变性。
看起来典型的方法是定义一个不可变的类 NSFoo
,然后从它派生一个可变的后代 NSMutableFoo
。通常,NSFoo
类定义了数据成员、getter 和只读操作,派生的 NSMutableFoo
添加了 setter 和变异操作。
由于对 C++ 更加熟悉,我不禁注意到这似乎与我在用 C++ 编写相同代码时所做的完全相反。虽然您当然可以采用这种方法,但在我看来更简洁的方法是创建单个 Foo
类,将 getter 和只读操作标记为 const
函数,并且还在同一个类中实现可变操作和 setter 。然后你会得到一个可变类,但类型 Foo const*
、Foo const&
等实际上都是不可变的等价物。
我想我的问题是,我对这种情况的看法是否合理?我理解为什么 Objective-C 以不同的方式做事,但是我错过了 C++ 中的两类方法的任何优势吗?还是我完全忽略了这一点?
这不是一个过于严肃的问题——更多的是出于我自己的好奇心。
最佳答案
Objective-C 过于动态。在 C++ 中,const 限定在编译时强制执行,而在运行时任何违反 const 限定的行为(例如通过非 const 限定指针修改 const 限定对象)都是未定义的行为。
这部分与Objective-C中没有私有(private)方法的原因相同。您可以自由地向任何对象发送任何消息。运行时分派(dispatch)接受一个对象和一条消息,并解析要调用的方法实现。
如果 const
合格的对象只能调用 const
合格的方法,这将完全破坏 Objective-C 和 Foundation 的动态特性,因为需要进行这样的检查在运行时(第一次检查将确定正在发送的消息是否解析为该特定实例的 const 限定实现,另一次检查以确定实例本身是否是 const 限定的)。考虑这个理论示例:
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)];
突然间你失去了活力。就像现在一样,可变和不可变对象(immutable对象)可以一起放在一个不可变或可变集合中。
拥有可变子类可以保持 Objective-C 的动态特性并保持运行时简单。前段时间有个类似的话题是关于私有(private)方法的。
关于c++ - Objective C 和 C++ 中的可变性设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3010791/