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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2012, 06:32   #1
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию Странности с полиморфизмом

Что вообще происходит с этим кодом?

Почему полиморфизм срабатывает (действительно срабатывает!) невзирая на то, что функция потомка отличается по сигнатуре?

Код:
struct Base {  virtual Base* clone() const = 0; };

struct Derived : public Base
{
    Derived* clone() const    {     std::cout<<"Создаю Derived\n";      Test();      return new Derived(*this);       }
    void Test() { std::cout<<"Test\n"; }
};

int main()
{  
 Base* ptr = new Derived;   ptr->clone(); //вывод: Создаю Derived  
}

И ещё такой вопрос: Если я действительно могу из базового класса запустить данный метод предка, то почему тогда я не могу сделать вот так:


Код:
struct Base {  virtual Base* clone() = 0; };

struct Derived : public Base
{
    Derived* clone() 
    {
        std::cout<<"Создаю Derived\n"; Test(); 
        Derived* ptr = new Derived;  return ptr;
    }
    void Test() const { std::cout<<"Test\n"; }
};

int main()
{
  Base* ptr = new Derived;
  (ptr->clone())->Test();      //: error C2039: Test: не является членом "Base"
}
Ведь результатом ptr->clone() должен быть реальный объект типа Derived!
То есть, метод Test() я уже запускаю для Derived, а не для базы!

Последний раз редактировалось _Bers; 03.02.2012 в 06:48.
_Bers вне форума Ответить с цитированием
Старый 03.02.2012, 09:18   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

http://programmersforum.ru/showthrea...=129110&page=2
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 03.02.2012, 10:02   #3
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

ррррр спасибо)
_Bers вне форума Ответить с цитированием
Старый 03.02.2012, 17:58   #4
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
Что вообще происходит с этим кодом?

Почему полиморфизм срабатывает (действительно срабатывает!) невзирая на то, что функция потомка отличается по сигнатуре?

Код:
struct Base {  virtual Base* clone() const = 0; };

struct Derived : public Base
{
    Derived* clone() const    {     std::cout<<"Создаю Derived\n";      Test();      return new Derived(*this);       }
    void Test() { std::cout<<"Test\n"; }
};

int main()
{  
 Base* ptr = new Derived;   ptr->clone(); //вывод: Создаю Derived  
}

И ещё такой вопрос: Если я действительно могу из базового класса запустить данный метод предка, то почему тогда я не могу сделать вот так:


Код:
struct Base {  virtual Base* clone() = 0; };

struct Derived : public Base
{
    Derived* clone() 
    {
        std::cout<<"Создаю Derived\n"; Test(); 
        Derived* ptr = new Derived;  return ptr;
    }
    void Test() const { std::cout<<"Test\n"; }
};

int main()
{
  Base* ptr = new Derived;
  (ptr->clone())->Test();      //: error C2039: Test: не является членом "Base"
}
Ведь результатом ptr->clone() должен быть реальный объект типа Derived!
То есть, метод Test() я уже запускаю для Derived, а не для базы!
Имя функции выбирается в соответствии со статическим типом указателя. В классе Base, указатель на тип которого имеет переменная ptr, не имеет такой функции с именем Test, а потому будет выдана соответствующая ошибка, что имя не найдено.
В первом же случае, так как функция clone объявлена в базовом классе и при этом виртуальна , то происходит динамическое связываниие за счет таблицы виртуальных функций.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 03.02.2012, 20:48   #5
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

я уже разобрался. Спасиб, Сыроежка)
_Bers вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
UnloadKeyboardLayout - странности Radical_Edward Win Api 0 29.01.2012 14:29
Странности с отступами evheniys HTML и CSS 7 06.06.2011 10:42
Странности с исключениями РагнаР Общие вопросы C/C++ 2 08.03.2011 22:56
странности ControlServiceEx() m_kostik Win Api 5 28.10.2010 20:39
Странности Chrome` а ]Wowan[ Софт 1 27.04.2009 04:11