Конструктор копирования должен вызывать метод, который зависит от объекта, но конструктор не может быть виртуальным - PullRequest
3 голосов
/ 27 октября 2010

У меня есть абстрактный базовый класс с двумя унаследованными классами.В обоих этих классах я определяю виртуальный метод, который используется конструктором.Теперь мне нужно создать конструктор копирования, но я не могу объявить конструктор копирования виртуальным, но я хочу, чтобы вызов метода внутри него зависел от типа объекта, который подается в качестве аргумента.Как я могу решить это?

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

По сути, мне нужен виртуальный конструктор копирования.

Ответы [ 6 ]

6 голосов
/ 27 октября 2010
  1. Будьте осторожны с вызовом виртуальных методов в конструкторах базового класса .
  2. Возможно, вы захотите использовать clone-метод .
3 голосов
/ 27 октября 2010

В конструкторе копирования класса T вы знаете, что копируемый объект относится к классу T.

Конструктор копирования не может создать объект производного класса.

Это конструктор копирования производного класса, который создает производную часть.

Значит, вы о чем-то запутались: вопрос не имеет смысла.

Представление примера может прояснить, в чем именно заключается путаница.

Приветствия & hth.,

1 голос
/ 27 октября 2010

Виртуальные функции, вызываемые во время конструктора / деструктора, не будут преобразованы в производный тип. Как заявлено Скоттом Майерсом здесь -

During base class construction, virtual functions never go down into derived classes. Instead, the object behaves as if it were of the base type.

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

0 голосов
/ 27 октября 2010

Есть хорошее обсуждение паттерна прототипа здесь , которое может быть полезным.

Прототип [Go4]

Проблема

«Фабричный» класс не может предвидеть тип "продукта" объектов, которые он должен создать.

Решение

Вывести все классы продуктов из абстрактный продукт базовый класс, который объявляет чистый виртуальный клон () метод. Базовый класс продукта также функционирует как фабрика продукции предоставление статического метода фабрики называется makeProduct (). Эта функция использует параметр описания типа для найти прототип в статическом Таблица прототипа поддерживается Товарный базовый класс. Прототип сам клонирует, и клон вернулся к звонящему.

Ссылка на 'Go4' относится к семенной книге по шаблонам проектирования , написанной авторами "Банды четырех".

0 голосов
/ 27 октября 2010

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

Однако при вызове виртуальной функции для копируемого объекта проблем не возникает, так как это уже полностью построенный объект. Вы также можете вставить в него «this», если эта функция знает, что передаваемый указатель еще не полностью создан. Таким образом:

T::T( const T & other )
{
   other.some_virtual_method(this); // legal but potentially dangerous
}

void T::some_virtual_method( T* other ) const
{
   other->another_virtual_method(); // dangerous in this situation
}
0 голосов
/ 27 октября 2010

Создайте виртуальный метод в объекте, который передается в качестве аргумента конструктору копирования, и вызовите его из конструктора копирования.При необходимости передайте 'this' этому методу.

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