Цель C, инициализирующая унаследованные переменные объекта подкласса

У меня есть класс MyClass. Я преувеличиваю, но предположим, что MyClass имеет 1000 переменных экземпляра. Затем я создаю подкласс с именем MySubClass со всеми переменными экземпляра, которые есть у MyClass, плюс еще одну.

Вопрос: для объекта MyObj класса MyClass существует ли простой способ создать соответствующий объект MyDerivedObj класса MySubClass, чтобы переменные экземпляра MyDerivedObj были такими же, как переменные экземпляра MyObj? Под «таким же» я подразумеваю точно такое же, в том смысле, что если переменная экземпляра MyObj является указателем на объект, соответствующая переменная экземпляра MyDerivedObj должна указывать на ту же память.


person William Jockusch    schedule 08.01.2010    source источник
comment
Но, возможно, я неправильно понял ваш вопрос. Вы хотите переопределить ivars в своем подклассе?   -  person Adrian Kosmaczewski    schedule 08.01.2010
comment
Нет, я не хочу ничего переопределять.   -  person William Jockusch    schedule 08.01.2010


Ответы (4)


По своей сути каждый экземпляр объекта будет иметь свой идентификатор; другой адрес и другая точка распределения в куче.

Таким образом, переменные экземпляра A и переменные экземпляра B всегда будут находиться в разных местах.

Теперь нет никаких причин, по которым переменные экземпляра A и B нельзя обернуть в структуру, которая выделяется отдельно. При этом тогда A и B могут иметь переменную экземпляра, которая является указателем на единственную копию структуры, полной значений.

Что касается настройки всех 1000 иваров, это также зависит от того, что вы хотите их установить. Если 0, то они будут установлены автоматически при создании экземпляра объекта. Если вы хотите bcopy() в шаблонном наборе значений, я бы посоветовал вам использовать указатель на структуру и выполнить отдельное выделение. Невозможно массово установить переменные экземпляра объекта, не делая предположений о макете, которые в конечном итоге вас укусят.

person bbum    schedule 08.01.2010

Должны ли все эти ивары быть отдельными? Если бы у меня была аналогичная проблема, моим первым побуждением было бы обернуть их в какую-то коллекцию ivar (NS (Mutable) Array/Dictionary/Set), а затем вы можете иметь на ней обычный геттер/сеттер и просто сделать

myDerivedObj.collection = myObj.collection;

Предполагая, что коллекция была свойством класса MyObj с политикой управления памятью «назначить», я думаю, что это должно сохранить ссылку на память.

(Я все еще новичок в этом, так что сбивайте любые недостатки/ошибки в моей логике.)

person Jaanus    schedule 08.01.2010
comment
Согласитесь, это похоже на вопрос, который намекает на гораздо большую проблему. КОМУ нужна тысяча экземплярных переменных в классе??!! - person Adam Woś; 08.01.2010
comment
У меня нет 1000 иваров. Я преувеличивал, чтобы прояснить основную проблему. Суть в том, что ivars достаточно многочисленны (и базовый класс все еще достаточно вероятно, чтобы измениться), так что, если бы мне пришлось копировать их один за другим, вместо этого я должен был бы подойти ко всему этому без подклассов. - person William Jockusch; 08.01.2010

Если ивары помечены как @public или @protected, да, они будут точно такими же.

person Adrian Kosmaczewski    schedule 08.01.2010
comment
Но тогда как мне выполнить назначение MyDerivedObj? Я ищу быстрый способ установить все 1000 иваров. - person William Jockusch; 08.01.2010

Я предлагаю вам создать инициализатор стиля «конструктор копирования» для родительского класса MyClass и вызвать его из инициализатора дочернего класса MyDerivedClass.

[MyDerivedClass initByCopying:someMyObject plusSomeNewProperties:stuff] ->
  [MyClass initByCopying:someMyObject] ->
    [NSObject init] -> // alloc, etc.

Вот некоторый псевдокод:

@interface MyClass : NSObject { 
  int AA;
  // ...
  int ZZ;
}   
@end

@implementation MyClass

-initByCopying:(MyClass*)other;
{
  if (self = [super init])
  {
    self.AA=other.AA;
    //...
    self.ZZ=other.ZZ;
  }
  return self;
}

@end

@interface MyDerivedClass {
  int AAA;
}
@end

@implementation MyDerivedClass 

-initByCopying:(MyClass*)other withNewValue:(int)newVar;
{
  if (self = [super initByCopying:(MyClass*)other])
  {
    self.AAA = newVar;
  }
  return self;
}

@end

Я подозреваю, что если у вас есть 1000 элементов-членов, вы, возможно, захотите рассмотреть возможность использования контейнера свойств или kvc для всех, кроме тех, которые чувствительны к производительности, что значительно упростит вашу процедуру initByCopying.

Может быть, есть ярлык для реализации конструктора копирования с использованием протокола копирования, но я не видел, как сделать его проще, чем в примере, который я привел выше.

person Alex Brown    schedule 08.01.2010