Структура для ортогонального списка
От: r1der Россия  
Дата: 23.11.10 10:50
Оценка:
template <typename T>
struct ListNode
{
  struct SubNode
  {
     SubNode(T val,ListNode * parent) : SubNode()
     {
         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
         this->parent=parent;
         *value=val;
     }

     SubNode(T val) : SubNode()
     {
         if (debug) cout<<"SubNode constructor(T)"<<endl;
         *value=val;
     }

     SubNode()
     {
         if (debug) cout<<"SubNode default constructor"<<endl;
         next=parent=0;
         value=new T();
     }

     ~SubNode()
     {
         if (debug) cout<<"SubNode destructor"<<endl;
         delete value;
     }

     void debug()
     {
       if (debug)
         cout<<"\n\n-------- DEBUG PRINT -------\nstruct SubNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nParent address:"<<parent<<"\n----------------------------\n\n";
     }

     T * value;
     SubNode * next;
     ListNode * parent;
  };

    ListNode()
    {
        if (::debug) cout<<"ListNode default constructor"<<endl;
        value=new T();
    }

    ListNode(T val) : ListNode()
    {
      if (::debug) cout<<"ListNode constructor(T)"<<endl;
      *value=val;
    }

    ~ListNode()
    {
        if (::debug) cout<<"ListNode destructor"<<endl;
        delete value;
    }

    void debug()
    {
      if (debug)
        cout<<"\n\n-------- DEBUG PRINT -------\nstruct ListNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nChild address:"<<child<<"\n----------------------------\n\n";
    }

    T * value;
    ListNode * next;
    SubNode * child;
};

template <typename T>
struct SpecialList
{
   SpecialList()
   {
       if (debug) cout<<"SpecialList default constructor"<<endl;
       head=new ListNode<T>();
   }
   SpecialList(T val)
   {
       if (debug) cout<<"SpecialList constructor(val)"<<endl;
       head=new ListNode<T>(val);
   }

   ~SpecialList()
   {
       ListNode<T> * temp;
       for (ListNode<T> * current=head; head->next!=0;)
       {
           if (current->next!=0) temp=current->next;
           cout<<"Delete element "<<current<<"\n";
           delete current;
           current=temp;
       }
   }
   ListNode<T> * head;
};


Имеются ли тут какие-то ошибки?
Как создать SubNode
ListNode::SubNode <int> ошибка, не получается.
Как проверить код на утечки памяти и "не красивые" места(стат.анализ)?
Может быть уже готовые структуры для этого, скажем в stl или boost, лучше первое конечно.
Лучше value везде хранить по указателю или же по значению? Делаю по указателю чтобы при копировании, например предавая в какой либо метод, или в качестве value выступает класс какой-нибудь, чтобы реже происхдило копирование этого объекта
Спасибо за ответы
icq 314624
Re: Структура для ортогонального списка
От: Eugene B.  
Дата: 23.11.10 14:31
Оценка:
Сразу бросается в глаза попытка вызвать один коструктор из другого, например:
SubNode(T val,ListNode * parent) : SubNode()

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

Еще нашел ошибку здесь:
next=parent=0;

parent и next — это указатели на разные типы (оператор присваивания parent=0 возврщает указатель на ListNode, а присваивать это дело пытается SubNode)

Пока что все, что могу сказать.

Здравствуйте, r1der, Вы писали:

R>
R>template <typename T>
R>struct ListNode
R>{
R>  struct SubNode
R>  {
R>     SubNode(T val,ListNode * parent) : SubNode()
R>     {
R>         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
         this->>parent=parent;
R>         *value=val;
R>     }

R>     SubNode(T val) : SubNode()
R>     {
R>         if (debug) cout<<"SubNode constructor(T)"<<endl;
R>         *value=val;
R>     }

R>     SubNode()
R>     {
R>         if (debug) cout<<"SubNode default constructor"<<endl;
R>         next=parent=0;
R>         value=new T();
R>     }

R>     ~SubNode()
R>     {
R>         if (debug) cout<<"SubNode destructor"<<endl;
R>         delete value;
R>     }

R>     void debug()
R>     {
R>       if (debug)
R>         cout<<"\n\n-------- DEBUG PRINT -------\nstruct SubNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nParent address:"<<parent<<"\n----------------------------\n\n";
R>     }

R>     T * value;
R>     SubNode * next;
R>     ListNode * parent;
R>  };

R>    ListNode()
R>    {
R>        if (::debug) cout<<"ListNode default constructor"<<endl;
R>        value=new T();
R>    }

R>    ListNode(T val) : ListNode()
R>    {
R>      if (::debug) cout<<"ListNode constructor(T)"<<endl;
R>      *value=val;
R>    }

R>    ~ListNode()
R>    {
R>        if (::debug) cout<<"ListNode destructor"<<endl;
R>        delete value;
R>    }

R>    void debug()
R>    {
R>      if (debug)
R>        cout<<"\n\n-------- DEBUG PRINT -------\nstruct ListNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nChild address:"<<child<<"\n----------------------------\n\n";
R>    }

R>    T * value;
R>    ListNode * next;
R>    SubNode * child;
R>};

R>template <typename T>
R>struct SpecialList
R>{
R>   SpecialList()
R>   {
R>       if (debug) cout<<"SpecialList default constructor"<<endl;
R>       head=new ListNode<T>();
R>   }
R>   SpecialList(T val)
R>   {
R>       if (debug) cout<<"SpecialList constructor(val)"<<endl;
R>       head=new ListNode<T>(val);
R>   }

R>   ~SpecialList()
R>   {
R>       ListNode<T> * temp;
R>       for (ListNode<T> * current=head; head->next!=0;)
R>       {
R>           if (current->next!=0) temp=current->next;
R>           cout<<"Delete element "<<current<<"\n";
R>           delete current;
R>           current=temp;
R>       }
R>   }
R>   ListNode<T> * head;
R>};

R>


R>Имеются ли тут какие-то ошибки?

R>Как создать SubNode
R>ListNode::SubNode <int> ошибка, не получается.
R>Как проверить код на утечки памяти и "не красивые" места(стат.анализ)?
R>Может быть уже готовые структуры для этого, скажем в stl или boost, лучше первое конечно.
R>Лучше value везде хранить по указателю или же по значению? Делаю по указателю чтобы при копировании, например предавая в какой либо метод, или в качестве value выступает класс какой-нибудь, чтобы реже происхдило копирование этого объекта
R>Спасибо за ответы
Re: Структура для ортогонального списка
От: Caracrist https://1pwd.org/
Дата: 23.11.10 18:28
Оценка:
Здравствуйте, r1der, Вы писали:

комментарии в коде:

R>
R>template <typename T>
R>struct ListNode
R>{
R>  struct SubNode
R>  {
/*
R>     SubNode(T val,ListNode * parent) // error can't compile: SubNode()
R>     {
R>         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
         this->>parent=parent;
R>         *value=val;
R>     }

R>     SubNode(T val) // error can't compile: SubNode()
R>     {
R>         if (debug) cout<<"SubNode constructor(T)"<<endl;
R>         *value=val;
R>     }

R>     SubNode()
R>     {
R>         if (debug) cout<<"SubNode default constructor"<<endl;
R>         next=parent=0;
R>         value=new T();
R>     }
*/ // то же самое одной строчкой
      SubNode(const T &val = T(),ListNode * par = NULL) 
         : value(new T(val)),
           parent(par),
           next(NULL)
      {
         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
     }


R>     ~SubNode()
R>     {
R>         if (debug) cout<<"SubNode destructor"<<endl;
R>         delete value;
R>     }

R>     void debug()
R>     {
R>       if (debug)
R>         cout<<"\n\n-------- DEBUG PRINT -------\nstruct SubNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nParent address:"<<parent<<"\n----------------------------\n\n";
R>     }

R>     T * value;
R>     SubNode * next;
R>     ListNode * parent;
R>  };
// то же самое с этими конструкторами
/*
R>    ListNode()
R>    {
R>        if (::debug) cout<<"ListNode default constructor"<<endl;
R>        value=new T();
R>    }

R>    ListNode(T val) // error can't compile: ListNode()
R>    {
R>      if (::debug) cout<<"ListNode constructor(T)"<<endl;
R>      *value=val;
R>    }
*/
R>    ~ListNode()
R>    {
R>        if (::debug) cout<<"ListNode destructor"<<endl;
R>        delete value;
R>    }

R>    void debug()
R>    {
R>      if (debug)
R>        cout<<"\n\n-------- DEBUG PRINT -------\nstruct ListNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nChild address:"<<child<<"\n----------------------------\n\n";
R>    }

R>    T * value;
R>    ListNode * next;
R>    SubNode * child;
R>};

R>template <typename T>
R>struct SpecialList
R>{
R>   SpecialList()
R>   {
R>       if (debug) cout<<"SpecialList default constructor"<<endl;
R>       head=new ListNode<T>();
R>   }
R>   SpecialList(T val)
R>   {
R>       if (debug) cout<<"SpecialList constructor(val)"<<endl;
R>       head=new ListNode<T>(val);
R>   }

R>   ~SpecialList()
R>   {
R>       //ListNode<T> * temp;
R>       for (ListNode<T> * current=head; current != NULL;)
/*head->next!=0 */ // удалил и сразу пошел по указателю...

R>       {
             ListNode<T> * temp;
R>           /*if (current->next!=0)*/ // зачем эта проверка?
             temp=current->next;
R>           cout<<"Delete element "<<current<<"\n";
R>           delete current;
//кто будет удалять SubNode? это оставлю реализовать тебе  :user: 
//а что если несколько ListNode/SubNode будут указывать на один и тот же SubNode? :crash: 
R>           current=temp;
R>       }
R>   }
R>   ListNode<T> * head;
R>};

R>


R>Имеются ли тут какие-то ошибки?

да
~~~~~
~lol~~
~~~ Single Password Solution
Re[2]: Структура для ортогонального списка
От: r1der Россия  
Дата: 23.11.10 18:39
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>Здравствуйте, r1der, Вы писали:


C>комментарии в коде:


R>>
R>>template <typename T>
R>>struct ListNode
R>>{
R>>  struct SubNode
R>>  {
C>/*
R>>     SubNode(T val,ListNode * parent) // error can't compile: SubNode()
R>>     {
R>>         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
         this->>>parent=parent;
R>>         *value=val;
R>>     }

R>>     SubNode(T val) // error can't compile: SubNode()
R>>     {
R>>         if (debug) cout<<"SubNode constructor(T)"<<endl;
R>>         *value=val;
R>>     }

R>>     SubNode()
R>>     {
R>>         if (debug) cout<<"SubNode default constructor"<<endl;
R>>         next=parent=0;
R>>         value=new T();
R>>     }
C>*/ // то же самое одной строчкой
C>      SubNode(const T &val = T(),ListNode * par = NULL) 
C>         : value(new T(val)),
C>           parent(par),
C>           next(NULL)
C>      {
C>         if (debug) cout<<"SubNode constructor(T,parent)"<<endl;
C>     }


R>>     ~SubNode()
R>>     {
R>>         if (debug) cout<<"SubNode destructor"<<endl;
R>>         delete value;
R>>     }

R>>     void debug()
R>>     {
R>>       if (debug)
R>>         cout<<"\n\n-------- DEBUG PRINT -------\nstruct SubNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nParent address:"<<parent<<"\n----------------------------\n\n";
R>>     }

R>>     T * value;
R>>     SubNode * next;
R>>     ListNode * parent;
R>>  };
C>// то же самое с этими конструкторами
C>/*
R>>    ListNode()
R>>    {
R>>        if (::debug) cout<<"ListNode default constructor"<<endl;
R>>        value=new T();
R>>    }

R>>    ListNode(T val) // error can't compile: ListNode()
R>>    {
R>>      if (::debug) cout<<"ListNode constructor(T)"<<endl;
R>>      *value=val;
R>>    }
C>*/
R>>    ~ListNode()
R>>    {
R>>        if (::debug) cout<<"ListNode destructor"<<endl;
R>>        delete value;
R>>    }

R>>    void debug()
R>>    {
R>>      if (debug)
R>>        cout<<"\n\n-------- DEBUG PRINT -------\nstruct ListNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nChild address:"<<child<<"\n----------------------------\n\n";
R>>    }

R>>    T * value;
R>>    ListNode * next;
R>>    SubNode * child;
R>>};

R>>template <typename T>
R>>struct SpecialList
R>>{
R>>   SpecialList()
R>>   {
R>>       if (debug) cout<<"SpecialList default constructor"<<endl;
R>>       head=new ListNode<T>();
R>>   }
R>>   SpecialList(T val)
R>>   {
R>>       if (debug) cout<<"SpecialList constructor(val)"<<endl;
R>>       head=new ListNode<T>(val);
R>>   }

R>>   ~SpecialList()
R>>   {
R>>       //ListNode<T> * temp;
R>>       for (ListNode<T> * current=head; current != NULL;)
C>/*head->next!=0 */ // удалил и сразу пошел по указателю...

R>>       {
C>             ListNode<T> * temp;
R>>           /*if (current->next!=0)*/ // зачем эта проверка?
C>             temp=current->next;
R>>           cout<<"Delete element "<<current<<"\n";
R>>           delete current;
C>//кто будет удалять SubNode? это оставлю реализовать тебе  :user: 
C>//а что если несколько ListNode/SubNode будут указывать на один и тот же SubNode? :crash: 
R>>           current=temp;
R>>       }
R>>   }
R>>   ListNode<T> * head;
R>>};

R>>


R>>Имеются ли тут какие-то ошибки?

C>да
icq 314624
Re[3]: Структура для ортогонального списка
От: r1der Россия  
Дата: 23.11.10 18:40
Оценка:
глюк, не соранилось, написал отдельной веткой
icq 314624
Re[2]: Структура для ортогонального списка
От: r1der Россия  
Дата: 23.11.10 18:48
Оценка:
Спасибо за указанные ошибки, теперь структуры выглядят вот так:

const int debug=1;
template <typename T>
struct SubNode
{
     SubNode(T val)
     {
         if (::debug) cout<<"SubNode constructor(T)"<<endl;
         next=0;
         value=new T();
         *value=val;
     }

     SubNode()
     {
         if (::debug) cout<<"SubNode default constructor"<<endl;
         next=0;
         value=new T();
     }

     ~SubNode()
     {
         if (::debug) cout<<"SubNode destructor"<<endl;
         delete value;
     }

     void debug()
     {
       if (::debug)
         cout<<"\n\n-------- DEBUG PRINT -------\nstruct SubNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\n----------------------------\n\n";
     }

     T * value;
     SubNode * next;
};
template <typename T,typename A>
struct ListNode
{
    ListNode()
    {
        if (::debug) cout<<"ListNode default constructor"<<endl;
        value=new T();
        next=0;
        child=0;
    }

    ListNode(T val)
    {
      if (::debug) cout<<"ListNode constructor(T)"<<endl;
      value=new T(val);
      next=0;
      child=0;
    }

    ~ListNode()
    {
        if (::debug) cout<<"ListNode destructor"<<endl;
        delete value;
    }

    void debug()
    {
      if (::debug)
        cout<<"\n\n-------- DEBUG PRINT -------\nstruct ListNode\nValue="<<*value<<"  Value address="<<value<<"\nNext address:"<<next<<"\nChild address:"<<child<<"\n----------------------------\n\n";
    }

    T * value;
    ListNode * next;
    SubNode<A> * child;
};
template <typename T,typename A>
struct SpecialList
{
   SpecialList()
   {
       if (debug) cout<<"SpecialList default constructor"<<endl;
       head=new ListNode<T,A>();
   }

   SpecialList(T val)
   {
       if (debug) cout<<"SpecialList constructor(val)"<<endl;
       head=new ListNode<T,A>(val);
   }

   bool AddNode(T val)
   {
       ListNode<T,A> * n=head;
       head=new ListNode<T,A>(val);
       head->next=n;
       return true;
   }

   bool DeleteNode(bool delete_head=0)
   {
     if ((!delete_head && head->next==0) or !head) return false;

     ListNode<T,A> * to_delete=head;
     head=head->next;
     if (to_delete->child)
     {
        SubNode<A> * curr, *temp;
        for (curr=to_delete->child; curr!=0;)
        {
           temp=curr->next;
           cout<<"Delete subitem "<<*(curr->value)<<endl;
           delete curr;
           curr=temp;
        }
     }else delete to_delete;
     return true;
   }

   bool AddSubNode(int num,A data)
   {
       ListNode<T,A> * temp;
       int counter=0;
       for (temp=head;temp!=0;temp=temp->next,++counter)
           if (counter==num) break;

       if (temp) {
         if (::debug) cout<<"AddSubNode as "<<num<<" element\n";
         SubNode<A> * t=new SubNode<A>(data);
         if (temp->child)
         {
             SubNode<A> * curr;
             for (curr=temp->child; curr->next!=0; curr=curr->next);
             curr->next=t;
             return true;
         }else {
           temp->child=t;
           return true;
         }
       }else return false;
   }

   ~SpecialList()
   {
       while(DeleteNode(true));
   }

   void Print()
   {
      int i=0;
      cout<<"\n\n-------- LIST PRINT ---------\n";
      for (ListNode<T,A> * current=head;current!=0;current=current->next,++i)
      {
        cout<<"Node "<<i<<" Value="<<*(current->value)<<endl;
        if (current->child!=0)
        {
          SubNode<A> * temp;
          cout<<"SubNodes: ";
          for (temp=current->child;temp!=0;temp=temp->next)
            cout<<*(temp->value)<<" ";
          cout<<"\n";
        }else cout<<"Not child\n";
        cout<<"\n";
      }
      cout<<"------------------------------\n\n";
   }

   ListNode<T,A> * head;
};



Но стоит вот какая задача, надо сделать SpecialList<строка 4 символа, строка 4 символа>
Не знаю как лучше реализовать, приходит вот такие решения
1) SpecialList<char *, char *> list("test")
Это неверно, но оно компилируется. Какой в итоге образуется ListNode?
Во что превращается T * value; из ListNode,в char ** value? Но как он тогда создается строкой value=new T(val);
что в данном случае происодит? Указатель на указатель инициализируется новым указателем на указатель временного объекта "test" в динамической памяти или же все таки создается в динамической памяти "test" и T здесь не ** а просто *
2) Special<string,string> не знаю как это будет работать по отношению к памяти, что здесь будет временным объектом, что будет создаваться. Полагаю что внутри в динамической памяти будет создавтаь новый объект стринг и туда будет копироваться значение временного стринга, но ведь стринг внутри и так работает на указателях?
3) SpecialList<char [],char []> Но тогда придется как-то поменять конструктор ListNode, чтобы тот умел сздавать и обычные объекты и массивы, как это сделать ума не приложу

cout<<typeid(list.head->value).name(); для первого случая показывает загадочное PPc, наверное намекает на то что это пипец))

И как ту можно использовать RTTI и dynamic_case для определения типа list.head->value?
Заранее большое спасибо за ответы.
icq 314624
Re[3]: Структура для ортогонального списка
От: Caracrist https://1pwd.org/
Дата: 23.11.10 19:05
Оценка:
Здравствуйте, r1der, Вы писали:

R>Спасибо за указанные ошибки, теперь структуры выглядят вот так:


http://codepad.org/fkyfZMAE — я не досчитался одного деструктора
код нужно проверять, и не на форуме...
~~~~~
~lol~~
~~~ Single Password Solution
Re[4]: Структура для ортогонального списка
От: r1der Россия  
Дата: 23.11.10 19:13
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>Здравствуйте, r1der, Вы писали:


R>>Спасибо за указанные ошибки, теперь структуры выглядят вот так:


C>http://codepad.org/fkyfZMAE — я не досчитался одного деструктора

C>код нужно проверять, и не на форуме...

хм странно, деструкторы все на месте

 ~SpecialList()
   {
       while(DeleteNode(true));
   }
 
     ~SubNode()
     {
         if (::debug) cout<<"SubNode destructor"<<endl;
         delete value;
     }

 ~ListNode()
    {
        if (::debug) cout<<"ListNode destructor"<<endl;
        delete value;
    }


а где тогда и как проверять?
icq 314624
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.