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

C++

Войти
Регистрация
Восстановить пароль
 
Observat
0 / 0 / 0
Регистрация: 29.01.2010
Сообщений: 5
#1

Создание дерева в родительском классе - C++

29.01.2010, 11:18. Просмотров 991. Ответов 9
Метки нет (Все метки)

Базовый класс используется для создания дерева. Потомки обрабатывают дерево по разному.
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
class A
{
public:
    A()
    {
        loadTree();
    }
    loadTree()
    {
        // заполнение данными c сервера
        // рекурсивно заполняется vector<A*>;
    }
//    method1() =0; // нельзя, т.к в loadTree() создается class A
private:
    vector<A*>;
};
 
class B1 : public A
{
public:
    B1() : A() {}
    method1()
    {
         // обработка данных
    }
//    method2(), ...
};
 
//class B2, B3 ...
Как изменить так, чтобы в loadTree() "рекурсивно заполнялся vector<Bn*>" и компилятор позволял в классе А написать method1() =0;
Т.е. пока получается дерево, где корень имеет тип Bn, а все ветви и листья - тип A. В итоге полиморфизм в таких деревьях не работает.
Я только 2 варианта вижу, оба не очень привлекательные:
1) в каждом Bn создавать метод loadTree();
2) в A создать метод method1(), который по какому нибудь признаку (можно ввести дополнительное поле для этого) через switch вызывает метод method1() соответствующего класса Bx.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.01.2010, 11:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Создание дерева в родительском классе (C++):

Создание объекта класса в другом классе!!! - C++
//----------------------------------Address.h---------------------------------------------------- class Address { public: const...

Создание процесса(Нитки) в отдельном классе - C++ Builder
Ситуация такая: Есть обычная WIN программка в Form1 имеем код #include &lt;vcl.h&gt; ... HANDLE hMainNetThread = NULL; ...

TreeView динамическое создание дерева - C++ Builder
Доброго дня. Пишу, но чувствую криво выходит, собственно, как ПРАВИЛЬНО - динамически создать дерево. Есть цикл, в нем по условию некие...

Создание динамического массива в классе - Visual C++
помогите пожалуйста написать задачу используя конструктор и деструктор(надо создать динамический массив в классе)... Дан динамический...

Ошибка: нет члена в родительском классе - C++
Добрый день! В коде ниже выбивает ошибку класс child не содержит члена g_out. include&lt;iostream&gt; using namespace std; class...

Можно ли переопределить функцию-член в унаследованном классе, не объявляя её виртуальной в родительском? - C++
Предположим, есть абстрактный класс Worker. class Worker { protected: char *myName; int value; private: ...

9
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
29.01.2010, 19:48 #2
Писать в A конструктор и virtual void method1() = 0; можно. Разумеется, не только void, но и любой другой тип.
0
Observat
0 / 0 / 0
Регистрация: 29.01.2010
Сообщений: 5
01.02.2010, 12:16  [ТС] #3
Если отфильтровать и переформулировать вопрос, то требуется решить следующее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A
{
public:
    A()
    {
        if(b)
            p = new Bx();    // как указать какой из Bi тут вызывать?
                      // требуется такой же тип, как у родителя
                      // т.е. Bi->Bi, а не Bi->A или Bi->Bk
       else  p = NULL;
    }
    A* p;
};
 
class Bi : public A
{
public:
    Bi() :  A() {}
};
Можно ли передать в качестве параметра тип, а не значение(и не указатель на функцию)? Есть ли в С++ что-либо похожее на parent в Java и можно ли оттуда извлечь тип? Или мне организовать какой-либо шаблон и как конкретно? Может еще варианты есть?

В первом посте ключевая фраза: "Получается дерево, где корень имеет тип Bn, а все ветви и листья - тип A. В итоге полиморфизм в таких деревьях не работает."
0
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
01.02.2010, 18:53 #4
Цитата Сообщение от Observat Посмотреть сообщение
В первом посте ключевая фраза: "Получается дерево, где корень имеет тип Bn, а все ветви и листья - тип A. В итоге полиморфизм в таких деревьях не работает."
Сначала надо разобраться, зачем нужно такое дерево, в котором полиморфизм не работает. Обычно при разборе таких ситуаций получается, что можно сделать так, чтобы и полиморфизм работал, и другие проблемы решались. Кроме того, в вышеприведённой фразе мне чудится какая-то путаница между типами объектов и типами указателей на них.
0
Observat
0 / 0 / 0
Регистрация: 29.01.2010
Сообщений: 5
02.02.2010, 10:05  [ТС] #5
Цитата Сообщение от Nick Alte Посмотреть сообщение
Сначала надо разобраться, зачем нужно такое дерево, в котором полиморфизм не работает.
У меня получается, а мне оно не надо, вот и спрашиваю как(!?)
можно сделать так, чтобы и полиморфизм работал, и другие проблемы решались
0
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.02.2010, 18:42 #6
Опиши проблему подробнее и обширнее. Зачем тебе надо такое дерево и из каких соображений оно именно такое? Чего ты хотел добиться?
0
Observat
0 / 0 / 0
Регистрация: 29.01.2010
Сообщений: 5
03.02.2010, 11:55  [ТС] #7
Данные хранятся на сервере в виде дерева(типа XML, "файловая система, где каталог - полноценный файл с данными", LDAP). В разных ветвях встречаются разные вещи.
Мы знаем узел, начиная от которого идут нужные данные, но внутренняя структура нам неизвестна. Поэтому для загрузки данных используем некий обобщенный метод; создаем класс А.
Каждый узел содержит атрибуты. Некоторые из них мы не используем, некоторые только читаем, другие можем редактировать/удалять/создавать. Мы можем также скрывать некоторые узлы, которые нельзя использовать. Для разных вещей(загруженных деревьев) узлы, атрибуты и их чтение/редактирование/использование/контроль могут отличаться. Создаются классы B1-Bn. Некоторые методы (или их части) одинаковые или их можно сделать одинаковыми без потерь. Такие методы выносим в класс А.
Класс А не может самостоятельно обрабатывать данные, поэтому сделаем его абстрактным.
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 A
{
public:
    A(char*/string/QString  str) {  loadTree(str);  }
    loadTree(char* root)
    {
        // заполнение данными c сервера
        // Рекурсивно заполняется vector<A*>;
//!    // но объектами (точнее указателями на созданные объекты)
//!    // не типа А, а типа Bx, который и вызвал конструктор класса А
    }
    void method1() =0;
    int method2() =0;
protected:
    ... // данные-атрибуты
    vector<A*>;
};
 
class B1 : public A
{
public:
    B1(char * root) : A(root) {}
    void method1() { ... }
    int method2() { ... }
protected:
// данных нет, они все в классе А
// могут быть только вспомогательные
};
 
void main()
{
  A* mas[2];
  mas[0] = new B1("qwerty");
  mas[1] = new B2("asd");
    ...
    mas[k]->method1();
}
Как сделать то , что отмечено "//!" ?

P.S. Неразвернутая по полочкам задача:
Клиент для LDAP-сервера для удобного добавления/редактирования DHCP, DNS, mail. Сейчас сделано по варианту 2 из первого поста, хочу сделать рефакторинг.
0
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
03.02.2010, 18:59 #8
Во-первых, напиши в описании класса A
C++
1
2
    virtual void method1() =0;
    virtual int method2() =0;
и пользуйся на здоровье. Это раз. Во-вторых, если ты хочешь, чтобы потомки заполняли вектор такими же потомками, пусть они и делают это невозбранно в своём собственном конструкторе и ссыпают полученные указатели в тот вектор, что объявлен в A.
1
Observat
0 / 0 / 0
Регистрация: 29.01.2010
Сообщений: 5
04.02.2010, 15:58  [ТС] #9
В класс А добавил абстрактную функцию newChild(). И в loadTree() строку "new A(...)" заменил на вызов этой функции. В классах Bi функция newChild() простая: { return new Bi(...); }
Все гениальное - просто! ))

Добавлено через 4 часа 33 минуты
Рано я радовался. Создаю второй объкт не доделав первый - примерно так компилятор ругается(ведь таблица виртуальных методов на этом этапе еще для класса А, не заменили ее еще на Вх).
Во-вторых, если ты хочешь, чтобы потомки заполняли вектор такими же потомками, пусть они и делают это невозбранно в своём собственном конструкторе и ссыпают полученные указатели в тот вектор, что объявлен в A
Это ничто иное как первый вариант первого поста, т.к. создавать без подключения к серверу не могу. Ведь неизвестно есть ли потомки, сколько их на уровне, сколько уровней?
0
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
04.02.2010, 18:51 #10
Объект класса Bx должен сам создавать объекты через new Bx(...), не вызывая при этом виртуальные методы. При этом указатели на полученные объекты заносятся в вектор, объявленный в A, но уже из конструктора Bx.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A{
public:
    virtual void Method() = 0;
protected:
    vector<A*> children;
};
 
class B1: public A{
public:
    B1(const char* str)
    {
        for(int i=0; i<20; +i)
            children.push_back(new B1(str));
    }
};
Если все производные классы создают детей одинаково, можно воспользоваться шаблоном и сэкономить на писанине.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A{
public:
    virtual void Method() = 0;
protected:
    vector<A*> children;
};
 
template<typename T>
void PopulateChildren(vector<A*> &children, const char* str)
{
    for(int i=0; i<20; ++i)
        children.push_back(new T(str));
}
 
class B1: public A{
public:
    B1(const char* str)
    {
        PopulateChildren<B1>(children, str);
    }
};
0
04.02.2010, 18:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.02.2010, 18:51
Привет! Вот еще темы с ответами:

Создание списка в классе - C++
Пытался создать список из объектов моего класса как закрытый член другого класса. Ну например class Player { private: ...

Создание объекта дочернего класса в родительском классе - Java
Подскажите, может кто знает, как в предке сосдать экземпляр потомка? или как сделать копию this? так чтобы при добавлении в...

Сделать геттеры и сеттеры для наследников в родительском классе - Java SE
Можно ли в родительском классе сделать геттеры и сеттеры для классов наследников если у них поля общие?

Изменить значение переменной в Родительском классе используя Потомственной класс - Visual Basic .NET
Всем привет. Я столкнулся с проблемой при выполнении одного задания. Хочу изменить значение переменной в Родительском классе используя...


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

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

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