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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Полиморфизм и позднее связывание, Borland C++ 3.1 
:(
    Опции темы
Morel
Дата 23.8.2004, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Понять одну вещь никак не могу.
Код

class Device
{
  ...
 public:
 virtual Message TranslateMessage()=0;
  ...
}

class Pshaiba : public Device
{
  ...
 public:
 Message TranslateMessage();
}

Pshaiba  p(2,2,2,2);
Pshaiba  *p1;
p1= new Pshaiba (1,1,1,1);
// или так p1=&p;
p1->TranslateMessage(); //вызов из Device, что нафиг не надо!
p.TranslateMessage();



При раннем связывании все нормально вызывается TranslateMessage() из класса Pshaiba. А вот при позднем из Device. Почему так происходит?

PM MAIL   Вверх
Конструктор
Дата 23.8.2004, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 10



Хм интересно как TranslateMessage вызывается из Device, если она там чисто-виртуальная функция?
PM MAIL WWW ICQ   Вверх
Morel
Дата 23.8.2004, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну вот так и вызывается:

Pure virtual function called

Я и спрашиваю почему она оттуда вызывается, а не из Pshaiba.
PM MAIL   Вверх
gray_k
Дата 23.8.2004, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 22



А как ты определил, что вызывается из Device? Она там у тебя объявлена нулевой, а значит реализации иметь не может. Мне кажется ты чего-то путаешь.


--------------------
С уважением.
Gray.
PM MAIL   Вверх
Конструктор
Дата 23.8.2004, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 10



Вот я написал у себя:

Код

#include <stdio.h>
#include <conio.h>

class Device
{
   public:
   virtual int TranslateMessage() = 0;
};

class Pshaiba: public Device
{
   public:
   virtual int TranslateMessage()
   {
       puts ("Translate message");
       return -1;
   };
};

int main()
{
   Pshaiba p;
   Pshaiba * p1;
   p1 = new Pshaiba();

   clrscr();

   p1->TranslateMessage();
   p.TranslateMessage();

   getch();

   return 1;
}


У меня оба раза выводится TranslateMessage. (BC 3.1)
Попробуй Options->Compiler->C++ Options->C++ Virtual tables->[X] Smart

PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 23.8.2004, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Может она из конструктора вызывается?


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
3,14
Дата 23.8.2004, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1614
Регистрация: 18.6.2004
Где: Н. Новгород

Репутация: нет
Всего: 24



Дык код правильно работает biggrin.gif В чём соль виртуальных ф-ий?
Код

Device *p = new Pshaiba();
p->TranslateMessage();

Выведет Translate message


--------------------
Может быть, это только мой бред,
Может быть, жизнь не так хороша,
Может быть, я не выйду на свет,
Но я летал, когда пела душа...
PM MAIL   Вверх
Morel
Дата 24.8.2004, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Это я напутал с конструктором Pshaiba. В нем вызывал
Код
Device::Device(id,numinput,numoutput,numdatchik);

Получилось, что вызывались два конструктора Device, по умаолчанию и мой с параметрами. Сделал инициализацию отдельной функцией в Device
Код
 init(id,numinput,numoutput,numdatchik);

Все заработало.
Вопрос теперь чисто теоретический. Почему p.TranslateMessage() работал правильно?
PM MAIL   Вверх
3,14
Дата 24.8.2004, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1614
Регистрация: 18.6.2004
Где: Н. Новгород

Репутация: нет
Всего: 24



Он и должен работать правильно, пер-ая p имеет тип Pshaiba и, следовательно, вызывает TranslateMessage описанный в Pshaiba

Это сообщение отредактировал(а) 3,14 - 24.8.2004, 09:59


--------------------
Может быть, это только мой бред,
Может быть, жизнь не так хороша,
Может быть, я не выйду на свет,
Но я летал, когда пела душа...
PM MAIL   Вверх
Vyacheslav
Дата 24.8.2004, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



ВСе таки надо поставить точки над i smile.gif
Сообщение
Pure virtual function called
Можно получить только в одном случае : вызвать виртуальную функцию в теле конструктора производного класса.
Это имело место или нет ?


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
lynx_916
Дата 24.8.2004, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Vyacheslav @ 24.8.2004, 11:04)
вызвать виртуальную

поправочка, чисто виртуальную, а это большая разницца. wink.gif


--------------------
Who dares, wins. (с) Solid Snake
PM MAIL ICQ YIM MSN   Вверх
Morel
Дата 25.8.2004, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



2: 3,14
Цитата
пер-ая p имеет тип Pshaiba

А p1 другой что ли?

Вот как это происходит.

Код

#include <stdio.h>

class Device
{
  protected:
  int id;
  public:
  Device::Device();
  Device::Device(int);
  init(int);
  virtual void TranslateMessage()=0;
};

class Pshaiba : public Device
{
 public:
 Pshaiba();
 Pshaiba(int);
 void TranslateMessage();
};

Device::Device()
{

}

Device::Device(int t)
{
 id=t;
}


Device::init(int i)
{
 id=i;
}

void Device::TranslateMessage()
{
 printf ("Dev=%d",id);
}

void Pshaiba::TranslateMessage()
{
 printf ("Psh=%d",id);
}

Pshaiba::Pshaiba()
{

}

Pshaiba::Pshaiba(int i)
{
//init(i);
Device::Device(i);

}


void main ()
{
 Pshaiba p(1);
 Pshaiba *p1;

 p1= new Pshaiba(2);

 p1->TranslateMessage();             //Pure virtual function called

 p.TranslateMessage();

}


Если в конструкторе Pshaiba вызвать init(), то все нормально.

PM MAIL   Вверх
Borisff2003
Дата 25.8.2004, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Сделал твой код он прекрасно делается без всякого init
И такой вот делается
Код

class Device
{

public:
virtual void TranslateMessage()=0;

};

class Pshaiba : public Device
{

public:
 virtual void TranslateMessage();
};

void Pshaiba::TranslateMessage()
{

};

int main ()
{
Pshaiba p;
Device *p1;

p1= new Pshaiba();

p1->TranslateMessage();            
p.TranslateMessage();
return 0;
}



--------------------
Лень, двигатель прогресса
PM MAIL WWW ICQ   Вверх
Morel
Дата 25.8.2004, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Странно у меня стабильно вылетает в BC 3.1, именно на строке
p1->TranslateMessage();.

Твой код понятно что будет работать. Я же говорил, что моя проблемма в конструкторах.
PM MAIL   Вверх
Vyacheslav
Дата 25.8.2004, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Прваивильно будет так
Код

Pshaiba::Pshaiba(int i):Device(i)
{

}




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 25.8.2004, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Цитата(lynx_916 @ 24.8.2004, 22:19)
Цитата(Vyacheslav @ 24.8.2004, )
вызвать виртуальную

поправочка, чисто виртуальную, а это большая разницца. wink.gif

Я имел в виду следущее
Код

class  Device
{
public:
Device(int i){init(i);}
Device(){}
virtual void TranslateMessage() = 0;
void init(int){ TranslateMessage();}
};

class Pshaiba : public Device
{

public:
Pshaiba(){  }
Pshaiba(int i):Device(i){  }
void TranslateMessage(){ std::cout << "Pshaiba";}
};

int main(int argc, char* argv[])
{
 Pshaiba p;
 Device* d = &p;
 d->init(1);   //  Ok   "Pshaiba"

 Pshaiba p1(1); //Error - вызов чистой виртуальной функции
}





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Конструктор
Дата 25.8.2004, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 10



Код

Device(int i){init(i);}
virtual void TranslateMessage() = 0;
void init(int){ TranslateMessage();}


ИМХО какой-то изврат, который все же работает как и должен, т.е. пытается вызывать чисто-виртульную ф-цию.
PM MAIL WWW ICQ   Вверх
Borisff2003
Дата 25.8.2004, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Morel
ВЕСЬ Приведенный тобой код работает в VC6.

А кстати, можно ли вызывать виртуальные функции из конструктора?

Это сообщение отредактировал(а) Borisff2003 - 25.8.2004, 13:21
--------------------
Лень, двигатель прогресса
PM MAIL WWW ICQ   Вверх
3,14
Дата 25.8.2004, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1614
Регистрация: 18.6.2004
Где: Н. Новгород

Репутация: нет
Всего: 24



А после компиляции gcc при запуске ошибку кидает


--------------------
Может быть, это только мой бред,
Может быть, жизнь не так хороша,
Может быть, я не выйду на свет,
Но я летал, когда пела душа...
PM MAIL   Вверх
Vyacheslav
Дата 25.8.2004, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Виртуальные функции вызывать из конструктора можно. Только нужно учитывать определенные особенности при вызове. Формально при вызове из конструктора она ведет себя как невиртуальная


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Borisff2003
Дата 26.8.2004, 05:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата

Виртуальные функции вызывать из конструктора можно. Только нужно учитывать определенные особенности при вызове. Формально при вызове из конструктора она ведет себя как невиртуальная

Что мы и имеем tounge.gif

Это сообщение отредактировал(а) Borisff2003 - 26.8.2004, 05:22
--------------------
Лень, двигатель прогресса
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 26.8.2004, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Кстати на заметку. В С++Builder VCL-ные классы(т.е. те которые являются производными от TObject) ведут себя иначе, нарушая стандарт. При вызове виртуальной функции в конструкторе, она вызывается именно как виртуальная. В результата в принципе возможно переопределять тело базового конструктора smile.gif
Код

class TBaseClass : public TObject
{
public:
    TBaseClass() { BaseConstuctorBody(); }
    virtual void BaseConstuctorBody(){ std::cout << "TBaseClass"; }
};

class TDerivedClass : public TObject
{
public:
    TDerivedClass() :TBaseClass(){ }
    //переопределяем тело базового конструктора  :)
    virtual void BaseConstuctorBody(){std::cout << "DerivedClass"; };
};

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


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Morel
Дата 26.8.2004, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем спасибо вроде разобрался.
Отдельное спасибо за Pshaiba::Pshaiba(int i):Device(i).
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0623 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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