Шаблоны разработки переменчивости в Objective C и C++

Недавно сделав некоторую разработку для iPhone, я приехал, чтобы заметить, что интересный шаблон разработки использовал много в iPhone SDK, относительно объектной переменчивости.

Кажется, что типичный подход там должен определить неизменный класс NSFoo, и затем получите из него изменяемого потомка NSMutableFoo. Обычно NSFoo класс определяет элементы данных, методы считывания и операции только для чтения и полученный NSMutableFoo прибавляет методы set и видоизменяющиеся операции.

Будучи более знакомым с C++, я не мог не заметить, что это, кажется, полное напротив того, что я сделал бы при написании того же кода в C++. В то время как Вы, конечно, могли проявить тот подход, мне кажется, что более краткий подход должен создать сингл Foo класс, методы считывания метки и операции только для чтения как const функции, и также реализуют изменяемые операции и методы set в том же классе. Вы затем закончили бы с изменяемым классом, но типами Foo const*, Foo const& и т.д. все - эффективно неизменный эквивалент.

Я предполагаю, что мой вопрос, делает мое взятие на ситуации, имеют смысл? Я понимаю, почему Objective C делает вещи по-другому, но является там какими-либо преимуществами для подхода с двумя классами в C++, который я пропустил? Или я упускаю суть полностью?

Не чрезмерно серьезный вопрос - больше для моего собственного любопытства, чем что-либо еще.

8
задан Mac 10 June 2010 в 00:20
поделиться

2 ответа

Objective-C слишком динамичен. В C ++ квалификация const применяется во время компиляции, и любые нарушения квалификации const во время выполнения (например, изменение объекта с квалификацией const с помощью указателя, не квалифицированного константой) являются неопределенным поведением.

Отчасти это та же причина, по которой в Objective-C нет частных методов. Вы можете отправить любое сообщение любому объекту. Диспетчер времени выполнения принимает объект и сообщение и разрешает вызов реализации метода.

если бы 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)];

Вы внезапно теряете динамику. В настоящее время изменяемые и неизменяемые объекты могут находиться вместе в неизменяемой или изменяемой коллекции.

Наличие изменяемого подкласса сохраняет динамическую природу Objective-C и упрощает выполнение. Некоторое время назад была похожая тема о частных методах.

4
ответ дан 6 December 2019 в 00:05
поделиться

Мысли...

Мак, как вы знаете, в C++, вы можете думать об "A" и "const A" как о двух различных типах, с их единственными отношениями

  1. "A" и "A &" могут быть неявно приведены к "const A" и "const A &", и т.д....
  2. "const A &" может быть const_cast в "A &", и т.д...

Компилятор обрабатывает наследование и распространение модификатора типа через выражения, и т.д.

Я бы предположил, что NS-специалисты выбрали соглашение ..Mutable... по нескольким причинам. Моя первая догадка заключается в том, что, как мне кажется, когда NextStep только зарождался, в C не было поддержки "const", и в нем все еще не было объектно-ориентированного подхода. И, что более важно, они хотели получить определенные оптимизации в своих реализациях изменяемых и неизменяемых объектов. Например, в классе неизменяемых строк, таком как NSString, может быть полезным "объединение" строк. Это позволяет распылять дубликаты строк и потенциально использовать меньше памяти. (Это имеет определенные недостатки, но всегда есть компромиссы.)

В C++ вы можете двигаться в том же направлении, сначала поняв copy-on-write. std::string, как говорят, делает это.

Interesting topic,
Уилл Брэдли

0
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: