Как заставить всех детей переопределить родительский метод Clone ()? - PullRequest
1 голос
/ 17 сентября 2008

Как сделать так, чтобы все производные классы C ++ / CLI переопределяли метод ICloneable :: Clone () базового класса?

Как вы думаете, я должен беспокоиться об этом? Или это не ответственность автора базового класса?

Поправка: Извините, я забыл упомянуть, что базовый класс является неабстрактным классом.

Ответы [ 9 ]

2 голосов
/ 17 сентября 2008

Ну, я не могу сказать, является ли это обязанностью базового класса или нет, и не попадет сюда в опасности контрактов на основе наследования.

В любом случае вы можете заставить некоторый класс переопределить метод - например, "Clone ()", сделав его чисто виртуальным членом абстрактного класса

public ref class ClonableBase abstract
{
 public:
   virtual void Clone() = 0;
}

обратите внимание на «абстрактный» и «= 0;». Аннотация позволяет классу содержать чистые виртуальные члены без предупреждения, а = 0; означает, что этот метод является чисто виртуальным, то есть он не содержит тела. Обратите внимание, что вы не можете создать экземпляр абстрактного класса.

Теперь вы можете

public ref class ClonableChild : public ClonableBase
{
 public:
   virtual void Clone();
}

void ConableChild::Clone()
{
  //some stuff here
}

Если у вас нет переопределения Clone в ClonableChild, вы получите ошибку компилятора.

2 голосов
/ 17 сентября 2008

Объявите это чисто виртуальным в базовом классе.

класс Base
{
...
витальная пустота Clone () = 0;
};

1 голос
/ 17 сентября 2008

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

virtual void Clone()
{
   throw gcnew NotSupportedException();
}

При этом производные классы должны будут переопределить метод, иначе ваше приложение встретит исключение NotSupportedException. По крайней мере, это сразу показало бы во время тестирования, что что-то не так. Это даст вам что-то для поиска, чтобы вы знали, когда сталкиваетесь с классом, который неправильно переопределяет Clone. В зависимости от степени вашего контроля над производными классами, это может быть важно для надежности.

1 голос
/ 17 сентября 2008

Объявите метод Clone () как абстрактный. Это должно работать, даже если родительский класс имеет конкретную реализацию.

Конечно, риск при применении таких вещей заключается в том, что автор производного класса будет раздражен, скажет: «Я не собираюсь использовать Клон в любом случае» и сделает что-то вроде побайтной копии или даже «вернет это». ", чтобы избавиться от ошибок.

0 голосов
/ 17 сентября 2008

прочитано это от травы Саттера. Это именно то, что вы спрашиваете

0 голосов
/ 17 сентября 2008

После некоторых размышлений я нашел это решение:

Object^ BaseClass::Clone()
{
  if(this->GetType() != BaseClass::typeid)
  {
    throw gcnew System::NotImplementedException("The Clone() method is not implemented for " + this->GetType()->ToString() + "!");
  }

  BaseClass^ base = gcnew BaseClass();
  ... // Copy the fields here
  return base;
}

Выдает исключение NotImplementedException, если вы пытаетесь клонировать экземпляр производного класса, который не переопределил метод Clone () базового класса.

0 голосов
/ 17 сентября 2008

Поправка: Извините, я забыл упомянуть, что базовый класс является неабстрактным классом.

В этом новом свете я почти уверен, что вы вообще не хотите заставлять кого-либо переопределять Clone (). Например, если мой производный класс не добавляет никаких полей, ему, вероятно, не нужен собственный специализированный метод Clone ().

0 голосов
/ 17 сентября 2008
class Base
{
...
virtual void Clone() = 0;
};

правильно.

Если вам нужно какое-то поведение по умолчанию для клона, попробуйте:

class Base
{
...
virtual void Clone()
{ 
   ...
   doClone();
   ...
};

...

private:
virtual void doClone() = 0;
};
0 голосов
/ 17 сентября 2008

Томас прав, но один из способов сделать этот класс абстрактным - определить чисто виртуальный метод.

Это делается, говоря:

virtual void Clone () = 0;

Если производный класс не реализует Clone, они не смогут его создать, поэтому у них не будет выбора, если они захотят, чтобы их класс был полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...