Можем ли мы сделать конструктор копирования класса виртуальным в C ++ - PullRequest
27 голосов
/ 27 марта 2012

Можем ли мы сделать конструктор копирования класса виртуальным в C ++? Как пользоваться?

Ответы [ 6 ]

24 голосов
/ 27 марта 2012

Нет, вы не можете, конструкторы не могут быть виртуальными.

C ++ 03 - 12.1 Конструкторы

4) Конструктор не долженбыть virtual (10,3) или static (9,4).[...]

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

4 голосов
/ 27 марта 2012

Нет, вы не можете.

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

Подумай об этом. Какую семантику будет иметь такой конструктор?

1 голос
/ 12 декабря 2015

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

Но это не значит, что это невозможно сделать с помощью небольшой магии C ++. :)

Есть несколько случаев, когда это невероятно полезно, например, сериализация не-POD классов. В этом примере создается конструктор виртуальной копии, который работает с использованием размещения new.

Предупреждение. Это пример, который может помочь некоторым пользователям с конкретными проблемами. Не делайте этого в общем коде. Сбой, если память, выделенная для нового класса, меньше, чем производный класс. Лучший (и единственный) безопасный способ использовать это, если вы управляете собственной памятью класса и используете новое размещение.

class VirtualBase
{
public: 
    VirtualBase() {}
    virtual ~VirtualBase() {}

    VirtualBase(const VirtualBase& copy)
    {
        copy.VirtualPlacementCopyConstructor(this);
    }

    virtual void VirtualPlacementCopyConstructor(void*) const {}
};

class Derived :: public VirtualBase
{
public:
    ...

    Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop
    {
    }

protected:
    void VirtualPlacementCopyConstructor(void* place) const
    {
        new (place) Derived(*this);
    }
};
1 голос
/ 27 марта 2012

Нет. C ++ является статическим типизированным языком, и компилятору C ++ бессмысленно создавать объект полиморфно. Компилятор должен знать тип класса для создания объекта. Другими словами, какой тип создаваемого объекта является решением времени компиляции с точки зрения компилятора C ++. Если мы сделаем конструктор виртуальным, компилятор отметит ошибку.

0 голосов
/ 11 июля 2018

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

Причина:

Виртуальный конструктор: - Невозможно, поскольку c ++ является языком статического типа и создает конструктор как виртуальный, поэтому компилятор не сможет решить, к какому типу объекта он относится, и оставить весь процесс на время выполнения из-за виртуального ключевого слова. Компилятор должен знать тип класса для создания объекта. Другими словами, какой тип создаваемого объекта является решением времени компиляции с точки зрения компилятора C ++. Если мы сделаем конструктор виртуальным, компилятор пометит ошибку.

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

0 голосов
/ 27 марта 2012

Никогда, это не возможно в C ++.

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