Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
RidgeA
11 / 0 / 0
Регистрация: 02.06.2015
Сообщений: 24
1

Копирование списка указателей на виртуальный класс

12.08.2015, 19:42. Просмотров 846. Ответов 3
Метки нет (Все метки)

Добрый день!
Подскажите, пожалуйста.
Имею примерно такой код

C++ (Qt)
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
class Abstract
{
public:
    int     mAbs;
 
    Abstract()
    {
    //...
    }
    virtual void method() = 0;
};
 
class A : public Abstract
{
public:
    int mA;
 
    A():
    Abstract()
    {
    //...
    }
 
    void method()
    {
    //...
    }
 
};
 
class B : public Abstract
{
public:
    int mB;
 
    B():
    Abstract()
    {
    //...
    }
 
    void method()
    {
    //...
    }
 
};
 
//...
 
QList <Abstract*> list;
    A *pA = NULL;
    B *pB = NULL;
 
    pA = new A();
    list.push_back(pA);
    //...
    pB = new B();
    list.push_back(pB);
Переменная "QList <Abstract*> list" является членом другого класса (пусть будет С).

Мне необходимо корректно организовать конструктор копирования класса С, таким образом, что бы все правильно сохранилось, в т. ч. члены классов А и В, которые не являются членами класса Abstract.

Я вижу единственный вариант - по какому-то полю type определять тип какой это класс А или В, создавать временную переменную соответствующего класса, копировать из поля list действующего класса, потом ее добавлять в list нового объекта.

Что-то вроде такого в конструкторе С (конструкторы копирования А и В реализованы):

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (int i = 0; i < other.list.size(); ++i)
{
    switch (other.type)
    {
        case A:
        {
            A* tmp = new A(*( (A*) list[i] ));
            break;
        }
        case B:
        {
            B* tmp = new B(*( (B*) list[i] ));
            break;
        }
        this->list.push_back(tmp);
    }
}
Корректный ли данный вариант?
Может существует более правильный способ?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2015, 19:42
Ответы с готовыми решениями:

Как создать класс со вложенной структурой указателей на класс?
В классе Concept хранится массив (точнее map) структур Rel. Сама же структура...

Копирование указателей
Здравствуйте дорогие товарищи. Имеется указатель на char, который читается с...

Виртуальный абстрактный класс
Надеюсь мой вопрос будет не глупым. Есть класс исключений в пространстве имен...

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

Виртуальный базовый класс
Создать иерархию типов, описывающую - человека, студента, отца семейства и...

3
DrOffset
8142 / 4723 / 1154
Регистрация: 30.01.2014
Сообщений: 7,693
12.08.2015, 19:53 2
Лучший ответ Сообщение было отмечено RidgeA как решение

Решение

Цитата Сообщение от RidgeA Посмотреть сообщение
Может существует более правильный способ?
Cделать копирующую виртуальную функцию clone(). В каждом наследнике переопределить на копирование соответствующего типа. В классе С просто пробежаться по списку, вызвая clone, результат сохранить в новый список.
Есть такой паттерн: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor

Добавлено через 4 минуты
Приближенный пример
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
class Abstract
{
public:
    Abstract();
 
    virtual void method() = 0;
    virtual Abstract * clone() const = 0;
};
 
class A : public Abstract
{
public:
    A();
 
    void method();
 
    A * clone() const { return new A(*this); }
};
 
class B : public Abstract
{
public:
    B();
 
    void method();
 
    B * clone() const { return new B(*this); } 
};
C++
1
2
3
4
for (int i = 0; i < other.list.size(); ++i)
{
    list.push_back(other.list[i]->clone()); 
}
1
RidgeA
11 / 0 / 0
Регистрация: 02.06.2015
Сообщений: 24
12.08.2015, 19:54  [ТС] 3
Цитата Сообщение от DrOffset Посмотреть сообщение
Cделать копирующую виртуальную функцию clone(). В каждом наследнике переопределить на копирование соответствующего типа. В классе С просто пробежаться по списку, вызвая clone, результат сохранить в новый список.
Т. е. примерно так, если я правильно понял?
C++ (Qt)
1
2
3
4
5
6
7
8
9
class A : public Abstract
{
//...    
    A(const Abstract* other)
    {
        mA = (A*) other->mA;
    }
//...
};
Я думал над таким вариантом уже после того, как написал сообщение :-)
0
DrOffset
8142 / 4723 / 1154
Регистрация: 30.01.2014
Сообщений: 7,693
12.08.2015, 19:55 4
Цитата Сообщение от RidgeA Посмотреть сообщение
Т. е. примерно так, если я правильно понял?
Нет, не совсем. Я обновил предыдущий пост, добавил пример.
Конструктор копирования у классов А и В используется стандартный. Вся суть в функции clone.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2015, 19:55

Виртуальный класс. Сигналы
#ifndef MODULE_H #define MODULE_H #include &lt;QWidget&gt; class Module :...

Указатель на виртуальный класс
Например у меня есть виртуальный класс Food и его нащадок Drink: class Food ...

Виртуальный методы, абстрактный класс.
Здравствуйте. Теоретические вопросы. Что такое виртуальный методы и что такое...


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

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

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