Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.88
KAlexey
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 7
#1

Создать копию объекта производного класса зная указатель на базовый - C++

09.01.2012, 15:05. Просмотров 2362. Ответов 4
Метки нет (Все метки)

Добрый день! Вопрос в следующем... Возможно ли создать копию объекта производного класса зная указатель на базовый класс? У меня получился вариант, приведенный ниже. Однако в нем не нравится функция clone которая динамически сравнивает типы с известными ей, и потом вызывает создание нового объекта, копия производного. Минус здесь, всегда приходится знать все типы производных классов от базового. Если появится новый придется делать исправления.
Какие еще возможны здесь варианты? Может есть вариант с использованием шаблонов или еще чего то? Заранее спасибо!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
 
using namespace std;
 
class Base
{
public:
  Base()
  {
     cout<<"Base constructor default"<<endl;
  };
  
  Base(const Base& obj)
  {
     cout<<"Base constructor copy"<<endl;
  };
  virtual ~Base() {;}
};
 
class Derived1:public Base
{
  public:
  Derived1()
  {
    cout<<"Derived1 constructor default"<<endl;
  }
 
  Derived1(const Derived1& obj)
  {
    cout<<"Derived1 constructor copy"<<endl;;
  }
};
 
class Derived2:public Base
{
  public:
  Derived2()
  {
    cout<<"Derived2 constructor default"<<endl;
  }
 
  Derived2(const Derived2& obj)
  {
    cout<<"Derived2 constructor copy"<<endl;;
  }
};
 
void clone(Base* pBase)
{
  cout<<"clone object"<<endl;
  if (Derived1 *p=dynamic_cast<Derived1*>(pBase)) new Derived1(*p) ;
  if (Derived2 *p=dynamic_cast<Derived2*>(pBase)) new Derived2(*p) ;
}
 
void main()
{
  Derived1 d1;
  Derived2 d2;
  Base* pBase =&d1;
  clone(pBase);
  pBase =&d2;
  clone(pBase);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2012, 15:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Создать копию объекта производного класса зная указатель на базовый (C++):

Как создать копию объекта, зная его указатель? - C++
Здравствуйте, существует следующая проблема. В своей программе я рисую график используя класс QwtPolarPlot. По нажатию на график, должно...

Вызов метода производного класса через указатель на базовый класс - C++
Всем привет ! Подскажите почему , при выполнении строки 45 я получаю ошибку ? А именно при выполнении выражения c-&gt;fnz() ...

Указатель на объект базового класса и адрес объекта производного класса - C++
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; } ~Class1() {delete j;}

Как создать копию объекта на который указывает указатель - C++
У меня есть указатель класс Student, который хранит информацию о студентах(имя, фамилию, телефон) в строках в стиле Си, то есть private...

Определить обработчик исключений на преобразование указателя базового класса на указатель производного класса - C++
Класс В является производным от класса А. Определить обработчик исключительной ситуации на преобразование указателя базового класса А на...

Присвоение указателю на базовый класс адреса производного класса - C++
Когда наследую как public,всё норм,как private - ошибка. Как сделать тогда,чтобы открылся конструктор? Base :: Base(); Не помогает ...

4
silent_1991
Эксперт С++
4985 / 3042 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
09.01.2012, 15:09 #2
KAlexey, clone можно сделать виртуальным методом класса Base, возвращающим указатель на Base. В каждом классе её надо переопределить так, чтобы она возвращала адрес нужного класса. Или, как вариант, использовать паттерн "Абстрактная фабрика".
0
KAlexey
0 / 0 / 0
Регистрация: 09.01.2012
Сообщений: 7
09.01.2012, 15:44  [ТС] #3
Спасибо Можно конечно перенести clone во внутрь классов, но мой вариант интересует чисто из позновательных целей, на понимание. Представим что в моей реализации мы сделаем Clone шаблонным, чтобы в него попадали различные указатели на разные базовые классы, что то типа

C++
1
2
3
4
5
6
7
8
template <class T>
void clone(T pBase)
{
  cout<<"clone object"<<endl;
  if (Derived1 *p=dynamic_cast<Derived1*>(pBase)) new Derived1(*p) ;
  if (Derived2 *p=dynamic_cast<Derived2*>(pBase)) new Derived2(*p) ;
  ...
}
естественно, что все производные классы я не перечислю, это помоему зло. при этом если вызвать
например typeid(*pBase).name() метод запросто покажет какого типа наш объект. Вот это и смущает
Думал может есть вариант чтото типа на лету динамически определить одной строкой тип объекта и создать его, ну чтото аля new typeid(*T)
0
silent_1991
Эксперт С++
4985 / 3042 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
09.01.2012, 15:46 #4
KAlexey, нет, так не получится. С++ - статически типизируемый язык, все типы всех создаваемых объектов должны быть известны на стадии компиляции.
1
Ilshat89
0 / 0 / 0
Регистрация: 29.08.2009
Сообщений: 12
08.05.2012, 22:37 #5
Столкнулся с такой же проблемой. Решил вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Base
{
public:
    virtual Base* clone() { return this; }
    virtual ~Base() {}
};
 
class Der1: public Base
{
    char c;
public:
    Der1(): c('m') {}
};
class Der2: public Base
{
    int n;
public:
    Der2(): n(682) {}
};
 
std::vector<Base*> list;
void func(Base *b) {
    Base *ptr = new Base(*b);
    ptr = b->clone();
    list.push_back(ptr);
}
 
int main()
{
    Der1 d;
    Der2 dd;
    func(&d);
    func(&dd);
 
    system("PAUSE");
    return 0;
}
В итоге, в векторе list будут указатели на иниц-ые объекты производных классов. Если что, clone можно переопределить в производных.

Добавлено через 3 часа 21 минуту
Цитата Сообщение от Ilshat89 Посмотреть сообщение
Столкнулся с такой же проблемой. Решил вот так:

C++
1
class Base...
В итоге, в векторе list будут указатели на иниц-ые объекты производных классов. Если что, clone можно переопределить в производных.
Извиняюсь, неправильно написал код, вот верный вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Base
{
public:
    virtual Base* clone() { return 0; }
    virtual ~Base() {}
};
 
class Der1: public Base
{
    char c;
 
public:
    Der1(): c('m') {}
    
    char& getc() { return c; }
 
    virtual Base* clone() {
        Der1 *p = new Der1;
        p->c = c;
        return p;
    }
};
class Der2: public Base
{
    int n;
public:
    Der2(): n(682) {}
 
    virtual Base* clone() {
        Der2 *p = new Der2;
        p->n = n;
        return p;
    }
};
 
std::vector<Base*> vvv;
void func(Base *b) {
    Base *ptr = b->clone();
    vvv.push_back(ptr);
}
 
int main()
{
    Node n1, n2, n3;
    Manager::ModifyNode(&n2);
    Manager::undoLast();
 
    Der1 d; //d.c = 'm';
    Der2 dd; //dd.n = 546;
    func(&d);
    func(&dd);
    d.getc() = 'a';
 
    system("PAUSE");
    return 0;
}
В первом варианте указатели в списке указывали на переданные объекты d и dd, а также глупо "утекала" память в функции func() В этом коде уже указатели указывают на новые объекты в памяти (копии d и dd). Строка d.getc() = 'a'; изменяет только объект d, а копия остается нетронутой.
0
08.05.2012, 22:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2012, 22:37
Привет! Вот еще темы с ответами:

Указателю на базовый класс присвоить адрес производного класса - C++
class Point { public: Point(float a=0, float b=0) { x=a; y=b; } protected: float x; float y; };

Как инициализировать элементы данных производного класса через базовый? - C++
есть базовый клас у него есть производный(открытое наследование), как инициализировать элементы-данных производного класа через базовый? ...

Использование перегруженного оператора ввода/вывода в поток базового класса для объекта производного класса - C++
Здравствуйте! Можно ли использовать перегруженный оператор ввода/вывода в поток из базового класса для объекта производного класса, если...

Задача (разъяснение) в алгоритм (программа, используя базовый и производный классы, создавала массив объектов типа производного класса) - C++
Задача на наследование классов, базовый класс - &quot;люди&quot;, производный - &quot;студенты&quot;...как я понял, а базовом надо создать символьную матрицу в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru