2010-09-30 7 views
0
#include<iostream> 
using namespace std; 

class Something 
{ 
    public: 
    int j; 
    Something():j(20) {cout<<"Something initialized. j="<<j<<endl;} 
}; 

class Base 
{ 
    private: 
    Base(const Base&) {} 
    public: 
    Base() {} 
    virtual Base *clone() { return new Base(*this); } 
    virtual void ID() { cout<<"BASE"<<endl; } 
}; 

class Derived : public Base 
{ 
    private: 
    int id; 
    Something *s; 
    Derived(const Derived&) {} 
    public: 
    Derived():id(10) {cout<<"Called constructor and allocated id"<<endl;s=new Something();} 
    ~Derived() {delete s;} 
    virtual Base *clone() { return new Derived(*this); } 
    virtual void ID() { cout<<"DERIVED id="<<id<<endl; } 
    void assignID(int i) {id=i;} 
}; 


int main() 
{ 
     Base* b=new Derived(); 
     b->ID(); 
     Base* c=b->clone(); 
     c->ID(); 
}//main 

На работающем:Создание клона объекта не работает с виртуальным базовым классом

Called constructor and allocated id 
Something initialized. j=20 
DERIVED id=10 
DERIVED id=0 

Мой вопрос связан с this, this и this пост.

В первой ссылке, Space_C0wb0y говорит

"Since the clone-method is a method of the actual class of the object, it can also create a deep-copy. It can access all members of the class it belongs to, so no problems there."

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

+0

Clone() - это не то, что вы видите (часто) на C++. Вы переносите приложение Java? –

+0

Нет. Я пытаюсь сделать глубокую копию на C++, и некоторые программисты на C++ создали собственную функцию clone(), как показано выше. Будет более понятно, когда вы будете следовать ссылкам, показанным в разделе «Мой вопрос связан с этим, этим и этим сообщением». (предложение в кавычках показано в моем вопросе выше) – Nav

ответ

5

Ну, ваш конструктор копирования ничего не делает, поэтому ваш метод клонирования ничего не делает на пути копирования.

См линия Derived(const Derived&) {}

EDIT: если вы добавляете код, чтобы скопировать присваиванием всех члены Derived, он станет неполной копией. Если вы также скопируете (создав новый экземпляр) свой экземпляр Something, он станет глубокой копией.

+1

+1! Код ничего не копирует. Для глубоких копий требуется, чтобы копирование выполнялось вручную в конструкторе копирования. – jwueller

+0

Я вижу. Поэтому единственной целью использования метода clone было вернуть указатель типа Base. В любом случае потребуется ручная копия. Вздох! Спасибо за ответы :) – Nav

+0

Небольшое дополнение: конструктор копирования по умолчанию создает мелкую копию. Если вам нужна небольшая копия чего-то, вам не нужно делать это вручную. – jwueller