Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование шаблонов в структуре данных Дерево 
:(
    Опции темы
Dogo
Дата 15.7.2007, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 20.2.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 9



Задача:"Разработать классы необходимые для реализации структуры дерево(не бинарное), с последующей возможностью хранения данных - Первый уровень вложенности - Дата, второй - Время, третий - Заметка"
Загвоздка в том что предпологается что узлы дерева будут хранить информацию различных типов. ума не приложу как такое реализовать.  В тупик загнали шаблоны, помогите разобраться. 

Node.h
Код

#pragma once
template <class NODE_DATA> 
class Node
{
private:
    static int count;
    int nodeID;
public:
    int GetNodeID(void);
    int GetCount(void);
    NODE_DATA GetData(void);
    NODE_DATA data;
    Node *previous;     //Указатель на предыдущий узел в ветви
    Node *next;           //Указатель на следущий узел в ветви
    Node *parent;       //Указатель на узел из которого пораждена ветвь в которой находится текущий узел
    Node *branch;       //Указатель на поражденую из текущего узла ветвь
    Node(NODE_DATA data_, Node *previous_, Node *next_, Node *branch_, Node *parent_);
    Node(void);
    ~Node(void);
};


Node.cpp
Код

#include "StdAfx.h"
#include ".\Node.h"
template <class NODE_DATA> 
int Node<NODE_DATA>::count=-1;

template <class NODE_DATA> 
Node<NODE_DATA>::Node(NODE_DATA data_, Node *previous_, Node *next_, Node *branch_, Node *parent_)
{
    nodeID=++count;
    data=data_;
    previous=previous_;
    next=next_;
    branch=branch_;
    parent=parent_;    
}
template <class NODE_DATA> 
Node<NODE_DATA>::Node(void)
{
    nodeID=++count;
    data=NULL;
    previous=next=branch=parent=NULL;    
}

template<class NODE_DATA>
int Node<NODE_DATA>::GetNodeID(void)
{
    return nodeID;
}

template<class NODE_DATA>
int Node<NODE_DATA>::GetCount(void)
{
    return count;
}

template <class NODE_DATA> 
Node<NODE_DATA>::~Node(void)
{
}



Tree.h
Код

#pragma once
#include ".\Node.h"
template<class ROOT_DATA>
class Tree
{
public:
    Node <char *> *root;
    Tree(void);
    ~Tree(void);
};


Tree.cpp
Код

#include "StdAfx.h"
#include ".\tree.h"
template <class ROOT_DATA>
Tree<ROOT_DATA>::Tree(void)
{    
    char data[8]="Notepad";
    root=new Node<char*> (data, NULL, NULL, NULL, NULL);
}

template <class ROOT_DATA>
Tree<ROOT_DATA>::~Tree(void)
{
}


Notepad.cpp
Код

#include "stdafx.h"
#include <conio.h>
#include <iostream>
#include ".\Node.cpp"
#include ".\Tree.cpp"
using std::cout;
using std::cin;

int main(void)
{    
    Node<int> * theNode=new Node<int>(123, NULL, NULL, NULL, NULL);
    Tree<void> * theTree=new Tree<void>;
    theTree->root->branch=theNode;
    getch();
    return 0;
}


При компиляции в Microsoft Visual Studio .NET 2003
Возникает такая ошибка :

notepad.cpp(13)  : error C2440: '=' : cannot convert from 'Node<NODE_DATA> *' to 'Node<NODE_DATA> *'
        with
        [
            NODE_DATA=int
        ]
        and
        [
            NODE_DATA=char *
        ]
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


Это сообщение отредактировал(а) Dogo - 15.7.2007, 21:56
--------------------
 
PM MAIL ICQ   Вверх
jonie
Дата 15.7.2007, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



ну все правильно..
Цитата

Код

template<class ROOT_DATA>
class Tree
{
public:
    Node <char *> *root;
    Tree(void);
    ~Tree(void);
};

зачем шаблонизирование, если оно не используется?! Мб пропустили как раз?)

root есть Node<char*>* , вы присваиваете ему Node<int>* .....

ежели так хотите поприсваивать на указателях - использовать явное приведение типов надо, однако, я пологаю, это не предпологалось.

Это сообщение отредактировал(а) jonie - 15.7.2007, 22:59


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Dogo
  Дата 15.7.2007, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 20.2.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 9



Да я понимаю, что тут без ошибки не могло обойтись. Собственно вопрос не в этом. Предпологается что дерево будет хранить несколько типов данных. Дату, время и заметку. Для каждого из которых созданы классы Date, myTime, Note. То есть узел может хранить как дату так и время. Но при моем коде если дерево создано с типом char * , то никакие другие типы использовать не получается. А нужно smile))
Вот как это реализовать я сообразить и не могу  smile 
--------------------
 
PM MAIL ICQ   Вверх
jonie
Дата 16.7.2007, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



используй void* (приведение в void* идет неявно) ; или приводи типы явно, например используя reinterpret_cast.
но вообще это так не делается.
Цитата

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

Код

typedef struct{
 typedef struct{
  TDate : date;
  TTime : time;
 }TTimeShtamp;
 TTimeShtamp timedate;
 TNote : note;
}TTreeItem,*PTreeItem;
 чем плохо?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Dogo
Дата 16.7.2007, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 20.2.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 9



Тем плохо, что каждый тип должен хранится в своем классе. дата в классе Date, время в классе Time, а заметка в классе Note. В свою очередь дерево состоит из связаных между собой объектов класса Node. Класс Node может в себе хранить объект класса Date, Time или Note. Не одновременно, а что-то одно, то есть первый уровень вложенности хранит Дату, второй Время, третий Заметку. 
Вот так дожно выглядеть дерево:
root                      // Node<char*>
  Date_1                   // Node<Date>
    Time_D1_1           // Node<Time>
    Time_D1_2           // Node<Time>
       Note_D1_T2_1  // Node<Note>
       ...
       Note_D1_T2_n  // Node<Note>
    ...
    Time_D1_t            // Node<Time>
  Date_2                   // Node<Date>
    Time_D2_1           // Node<Time>
     ...                        
     Time_D2_t1        // Node<Time>
  ...
  Date_d                   // Node<Date>
   
 smile             

Это сообщение отредактировал(а) Dogo - 16.7.2007, 01:22
--------------------
 
PM MAIL ICQ   Вверх
jonie
Дата 16.7.2007, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



ну можно пойти как тупые американцы )
Код

/* abstract */
class NodeBase {
 ...какие-то общие для всех листьев методы...
.... типа hasChilds() ...
};

class DateNode : public NodeBase {
 ..
};

class TimeNode : public NodeBase {
 ..
};

class NoteNode : public NodeBase {
..
};

в дереве же хранить NodeBase*.... и делать соотв. приведение типов)
а можно просто void* о чем я говорил ранее....

вообще можно пойти еще более простым путем :
имеем vector<TDate>, каждый элемент TDate имеет "в себе" vector<TTime>, каждый элемент TTime имеет "в себе" vector<Tnode>.
если б0льшая вложенность не предусматривается).. ну и vector можно заменить на иной контейнер. и забыть про дерево )

Это сообщение отредактировал(а) jonie - 16.7.2007, 10:19


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Dogo
Дата 16.7.2007, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 20.2.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 9



Можно поподробнее о приведении производных типов... smile  smile
--------------------
 
PM MAIL ICQ   Вверх
jonie
Дата 16.7.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



это ООП в C++. Почитай учебник.
вкратце
Код

class Base { };
class D : public Base {};

D objD;
Base objB;

Base* lpB = &objD; //ok. указатель на базу может хранить указатели на потомков без дополнительных изворотов) и может вызывать вирт. функции.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Dogo
Дата 17.7.2007, 05:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 20.2.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 9



Спасибо.  smile Такое возможно только если класс D унаследован от класса Base? Если я хочу использовать приведение типов для абсолютно независимых друг от друга классов, то мне  нужно использовать reinterpret_cast или это не тот случай? 
--------------------
 
PM MAIL ICQ   Вверх
jonie
Дата 17.7.2007, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



reinterpret_cast служит для преобразования указателей, а не "классов".
т.е.
Код

Base obj;
char* p = reinterpret_cast<char*>(&obj); //ok. явное приведение типов.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0502 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.