2014-12-05 2 views
2

У меня возникла проблема с конструкторами копирования ... Я предполагаю, что есть основной ответ на это, и я пропускаю что-то очевидное - возможно, я делаю что-то совершенно неправильное - но я не смог понять это.Проблема с конструктором экземпляра C++ с родительскими/дочерними классами

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

Вот пример псевдокода, если это помогает:

// Base classes 
class ItemRev { 
    ... 
} 

class Item { 

protected: 

vector<ItemRev *> m_revPtrVec; 

} 


Item::Item(const Item &inputItemObj) 
{ 
    // Copy contents of the input object's item rev pointer vector 
    vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revPtrVec).begin(); 
    while (vecIter != (inputItemObj.m_revPtrVec).end()) { 
    (this->m_revPtrVec).push_back(new ItemRev(**vecIter)); 
    } 
} 

========= 

// Derived classes 
class JDI_ItemRev : public ItemRev { 
    ... 
} 

class JDI_Item : public Item { 

... 

} 

JDI_Item::JDI_Item(const JDI_Item &itemObj) 
{ 
    // Copy contents of the input object's item rev pointer vector 
    vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revObjPtVec).begin(); 

    // The below does not work! 
    while (vecIter != (inputItemObj.m_revObjPtVec).end()) { 
    m_revObjPtVec.push_back(new JDI_ItemRev(**vecIter)); 
    } 
} 

Проблема с выше в push_back() вызова в конструкторе JDI_Item копирования.

С учетом этой настройки, как должен выглядеть конструктор копии дочернего класса? Мне даже нужен конструктор экземпляров дочернего класса? Я предположил, что сделал, потому что конструктор копирования создает новые объекты, а родительский конструктор копии создаст новые объекты, которые не являются типом, который я хочу в производном классе (т. Е. Родительский объект хранит указатели на объекты ItemRev, тогда как дочерний объект следует хранить указатели до полученных JDI_ItemRev объектов).

+0

Вам потребуется копирования из-базы конструктор, то с подписью 'JDI_Item :: JDI_Item (Const ItemRev &)'. Этот конструктор не генерируется для вас по умолчанию, потому что он редко имеет смысл. – cdhowie

+0

Во-первых, 'JDI_Item'-ctor неисправен. Он течет, если вызывается какое-либо исключение. Почему у вас есть 'std :: vector' указателей на' JDI_ItemRev'? Почему они не попадают прямо в вектор или, по крайней мере, управляются умными указателями? (В первом случае неявное определение должно работать.) То же самое можно сказать о 'Item'. – Deduplicator

ответ

1

Как упоминалось в комментариях, возможно, существует более краткий способ выражения этой проблемы (т. Е. Ваша структура классов нуждается в некоторой работе).

Однако, если вы хотите сделать это, самым простым способом добиться этого является использование виртуального метода clone() в базовом классе ItemRev с переопределениями, определенными в производных классах.

.: например

class ItemRev { 

    virtual ItemRev* clone() const = 0; 
}; 

class JDI_ItemRev : public ItemRev { 

    ItemRev* clone() const override 
    { 
    // do your actual cloning here, using the copy constructor 
    return new ItemRev(*this); 
    } 
}; 

Теперь, когда вы звоните clone() на любом классе, производном от ItemRev, вы будете возвращены ItemRev*, но он будет указывать на полностью сконструированный производный класс. Разумеется, вы можете перейти к интерфейсу производного класса с static_cast<> или dynamic_cast<>.

... однако ...

вывод часто кажется, что легко выиграть, но часто оказывается не быть. Наследование следует использовать только в том случае, если производный класс действительно является типом базового класса. Часто люди выбирают наследование, когда производный класс много похож на базовый класс, или обладает многими характеристиками с базовым классом. Это не время использовать наследование. Пришло время использовать инкапсуляцию.

В общем, наследование - это зло.

С другой стороны, вы можете найти эту ссылку интересной.

Presentation on inheritance as an implementation detail

Смежные вопросы