Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.01.2012, 11:51   #1
Archet
Пользователь
 
Регистрация: 04.12.2011
Сообщений: 13
По умолчанию Правильна ли такая реализация списка из указателей на базовый класс?

Есть вот такая вот структура, являющаяся элементом списка

Код:
struct PList{
      Pack*content;
      PList*next;};
Pack - базовый класс, для которого существует чисто виртуальная функция
void show();. От него наследованы несколько классов, в каждом их которых переопределена эта функция.

Элемент списка создается в общем случае таким способом:
Код:
PList*temp=head;
          if (temp==NULL){temp=new PList; temp->content=new PackMail; temp->next=NULL;}
          else {while (temp->next!=NULL) {temp=temp->next;}; 
          temp->next=new PList; temp=temp->next; temp->content=new PackMail; temp->next=NULL;}
где PackMail - класс-потомок.

Правильна ли такая реализация прохода списка с вызовом show(); для всех элементов?

Код:
showall(PList*head){
     PList * temp=head; 
     while (temp->next!=NULL){
           temp->content->show();
           temp=temp->next;}
}

Последний раз редактировалось Archet; 18.01.2012 в 11:56.
Archet вне форума Ответить с цитированием
Старый 18.01.2012, 11:59   #2
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

да. функция будет вызвана благодаря виртуальной таблице, в которой хранятся указатели на требуемые функции
counter вне форума Ответить с цитированием
Старый 18.01.2012, 12:02   #3
Archet
Пользователь
 
Регистрация: 04.12.2011
Сообщений: 13
По умолчанию

Однако что-то у меня явно не так, ибо программа падает при попытке вообще любого обращения вида
Код:
temp->content->%function name%
(обращение к любой функции, общей для всех классов-потомков)

Ни о какой конкретной ошибке не сигналит, слетает с лаконичным "Прекращена работа программы".

Что может вызывать подобную проблему?

Последний раз редактировалось Archet; 18.01.2012 в 12:11.
Archet вне форума Ответить с цитированием
Старый 18.01.2012, 12:17   #4
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Archet Посмотреть сообщение
Однако что-то у меня явно не так, ибо программа падает при попытке вообще любого обращения вида
Код:
temp->content->%function name%
(обращение к любой функции, общей для всех классов-потомков)

Ни о какой конкретной ошибке не сигналит, слетает с лаконичным "Прекращена работа программы".

Что может вызывать подобную проблему?
телепаты в отпуске
_Bers вне форума Ответить с цитированием
Старый 18.01.2012, 12:20   #5
Archet
Пользователь
 
Регистрация: 04.12.2011
Сообщений: 13
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
телепаты в отпуске
Резонно.
Тогда совсем уж идиотский вопрос - как в Win7 при использовании Dev C++ добиться более подробных комментариев о причинах закрытия программы?

Нет, на гугле меня не банили. Но найти что-то по этому вопросу не получается.

Последний раз редактировалось Archet; 18.01.2012 в 12:28.
Archet вне форума Ответить с цитированием
Старый 18.01.2012, 12:28   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Archet Посмотреть сообщение
Резонно.
Тогда совсем уж идиотский вопрос - как в Win7 при использовании Dev C++ добиться более подробных комментариев о причинах закрытия программы?
Бес понятия.

Локализируй проблему: сделай отдельный мини-проект, с минимум исходного кода, и выложи сюда.

Нужно видеть весь код, а не обрывки, что бы понять что именно не так.

/ps в приведенных выше фрагментах есть что-то такое "фейловое". Общее впечатление, что у тебя конструкция переосложнена по причине нарушения инкапсуляции.

Допустим, ты сделал связанный список (аналог std::list)
Связанный список - это контейнер, который умеет хранить внутри себя элементы, не утруждая себя деталями их внутренней реализации.

А ты взял и вынес виртуальный(!) метод за пределы самого элемента, свалив его на голову многострадального списка.

Ты уверен, что это именно то, что тебе было нужно?
Почему твой контейнер оказывается должен знать детали реализации подопечных объектов, и учитывать особенности их строения?
_Bers вне форума Ответить с цитированием
Старый 18.01.2012, 12:34   #7
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Archet, как создается список? может там нулевой указатель?

Попробуй заверни проблемный код в try/catch
counter вне форума Ответить с цитированием
Старый 18.01.2012, 12:39   #8
Archet
Пользователь
 
Регистрация: 04.12.2011
Сообщений: 13
По умолчанию

Мини-проект сейчас сделаю.

А пока еще один вопрос:
_Bers, как в общих чертах должна выглядеть правильная реализация такого списка и вызов этого виртуального метода для содержащихся в нем объектов класса-потомка?

Цитата:
Сообщение от counter Посмотреть сообщение
Archet, как создается список? может там нулевой указатель?

Попробуй заверни проблемный код в try/catch
В первом посте указал, как создается первый и последующие элементы списка. Там вроде бы не должно получаться нулевого указателя в любом случае.

Try\catch сейчас тоже испытаю.

Последний раз редактировалось Archet; 18.01.2012 в 12:45.
Archet вне форума Ответить с цитированием
Старый 18.01.2012, 13:11   #9
Archet
Пользователь
 
Регистрация: 04.12.2011
Сообщений: 13
По умолчанию

Итак, через try-catch ничего так и не поймал. Как молча падало, так и падает.

А вот запрошенный код мини-проекта. В правильной работе функций добавления элемента и задания полей класса я уверен (эти функции протестировались нормально, без каких-либо ошибок), поэтому привожу их в максимально простом и коротком виде для 2х полей типа int.


Код:
class Pack{
      protected:
              int data1;
      public:
              Pack(){data1=0;}
              void set_d1(int k){data1=k;}
              virtual void show()=0;
              virtual int get_cat()=0;
      };


class PackMail : public Pack{
      private:
              int data2;
      public:
             PackMail(){data1=0; data2=0;}
             void set_d2(int k){data2=k;}
             void show(){cout<<"data1="data1<<endl<<"data2="<<data2;}
             int get_cat(){return 1;}
};

struct PList{
      Pack*content;
      PList*next;};
      

class ServTable{
      private:
              PList * head;
      public:
             ServTable(){head=NULL;};
             void AddPack();
             void showall();          
             };
             
void ServTable::AddPack()
{
          PList*temp=head;
          if (temp==NULL){temp=new PList;
          temp->content=new PackMail; 
          temp->next=NULL;
          }
          else {
               while (temp->next!=NULL) {
                     temp=temp->next;
                     }; 
          
          temp->next=new PList; 
          temp=temp->next; 
          temp->content=new PackMail; 
          temp->next=NULL;}
     
     cout<<"input data1 : "<<endl;
     int t1;
     cin>>t1;
     temp->content->set_d1(t1);
     
     cout<<"input data2 : "<<endl;
     cin>>t1;
     temp->content->set_d2(t1);
     }
     
void ServTable::showall(){
     PList * temp=head; 
     while (temp->next!=NULL){
           temp->content->show();
           temp=temp->next;
           }
}

int main(int argc, char *argv[])
{  ServTable test;
   test.AddPack();
   test.showall();
   
   system("PAUSE");
   return EXIT_SUCCESS;
}
Archet вне форума Ответить с цитированием
Старый 18.01.2012, 13:51   #10
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от Archet Посмотреть сообщение
В правильной работе функций добавления элемента и задания полей класса я уверен (эти функции протестировались нормально, без каких-либо ошибок), поэтому привожу их в максимально простом и коротком виде для 2х полей типа int.
ну ну ну... погорячился...

Говорил я, что указатель нулевой? Почему отладчиком не прошелся?

Код:
if (temp==NULL){temp=new PList;
		temp->content=new PackMail; 
		temp->next=NULL;
		head=temp; // кто указатель на место вернет?
		}
И этот мини-проект не мешало бы перед постингом скомпилировать!

Код:
((PackMail*)temp->content)->set_d2(t1); // приводить типы тоже надо
counter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Абстрактный базовый класс(задача) friman134 Общие вопросы C/C++ 2 17.12.2011 21:51
АТД: Реализация списка с использованием указателей Suslik963 Помощь студентам 1 17.11.2010 10:06
результат базовый класс и наследование Пепел Феникса Общие вопросы C/C++ 1 21.09.2010 02:29
Создать базовый класс sT1mfy Общие вопросы Delphi 3 11.06.2010 21:38
Вернут указатель на базовый класс Crucian Общие вопросы C/C++ 2 08.11.2007 18:10