Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Kaskera
0 / 0 / 0
Регистрация: 27.07.2013
Сообщений: 34
#1

Виртуальность и наследование - C++

03.09.2013, 12:57. Просмотров 363. Ответов 8
Метки нет (Все метки)

Очень интересный вопрос!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
class Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    public: virtual ~Super() {}
};
 
class Sub : public Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};
 
int main() {
    Super *obj = new Sub();
    // how to call 'Super::print()' from 'obj'
    // without using operator '.' and/or '->'?
    delete obj;
}
Как вызвать Super :: print() с obj, не используя операторы '.' или '->' ?
Автор пишет, что на первый взгляд все просто, но это не так. Если есть решение, скомпилируйте его. Всегда вызывается Sub :: print ().
Только одно решение известно.

http://ideone.com/wwsksb

Покажите свои варианты.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2013, 12:57     Виртуальность и наследование
Посмотрите здесь:

Перегрузка Виртуальность - C++
Чем отличается перегрузка от виртуальности?

Наследование - C++
Прошу помочь реализовть программу. Задание на русском: Разработать класс CFile,который инкапсулирует в себя такие функции работы с...

Наследование c++ - C++
Здравствуйте. Есть абстрактный класс : class GeometryFigures { private: string Name; public: void setName(string Name_new);...

Наследование - C++
Создаю базовый класс: #include &lt;string&gt; using namespace std ; class T { protected: string name ;

Наследование - C++
Если я объявлю класс A, как базовый для класса B, то есть вот так: class B : public A { ... }; То в методах класса B будут...

Наследование в С++ - C++
Здравствуйте! #include &lt;iostream&gt; using namespace std; class exp{ public: virtual exp* diff()=0; virtual void...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
Эксперт С++
15295 / 6927 / 1096
Регистрация: 02.05.2013
Сообщений: 11,334
Завершенные тесты: 1
03.09.2013, 13:28     Виртуальность и наследование #2
В нормальном приложении я бы сделал так:

Вариант 1, нормальный (но не по условию):
C++
1
2
   
obj->Super::print();
Вариант 2:
C++
1
2
3
typedef void (*PFUNC)(void *);    
PFUNC pFunc = (PFUNC)&Super::print;
pFunc(obj);
Ну а как еще вызвать метод объекта, не используя операторы "." и "->" ?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.09.2013, 13:36     Виртуальность и наследование #3
Убежденный, Ой-ой-ой. Поправьте, если я ошибаюсь, но данный код вполне себе может привести к UB, ибо нигде не гарантируется, что sizeof(function-pointer) == sizeof(pointer to member-function) да и вообще не факт что скомпилируется.

C++
1
2
void (Super::*fp)() const = &Super::print;
(obj->*fp)();
Операторы ./-> не используются, а про ->*/.* сказано ничего не было.
Kaskera
0 / 0 / 0
Регистрация: 27.07.2013
Сообщений: 34
03.09.2013, 13:39  [ТС]     Виртуальность и наследование #4
Цитата Сообщение от Убежденный Посмотреть сообщение
В нормальном приложении я бы сделал так:

Вариант 1, нормальный (но не по условию):
C++
1
2
   
obj->Super::print();
Вариант 2:
C++
1
2
3
typedef void (*PFUNC)(void *);    
PFUNC pFunc = (PFUNC)&Super::print;
pFunc(obj);
Ну а как еще вызвать метод объекта, не используя операторы "." и "->" ?
Error 1 error C2440: 'type cast' : cannot convert from 'void (__thiscall Super::* )(void) const' to 'PFUNC'
Убежденный
Системный программист
Эксперт С++
15295 / 6927 / 1096
Регистрация: 02.05.2013
Сообщений: 11,334
Завершенные тесты: 1
03.09.2013, 13:46     Виртуальность и наследование #5
Цитата Сообщение от Kaskera Посмотреть сообщение
Error 1 error C2440: 'type cast' : cannot convert from 'void (__thiscall Super::* )(void) const' to 'PFUNC'
http://ideone.com/CisVko

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
 
class Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    public: virtual ~Super() {}
};
 
class Sub : public Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};
 
int main() {
    Super *obj = new Sub();
    // how to call 'Super::print()' from 'obj'
    // without using operator '.' and/or '->'?
    
    typedef void (*PFUNC)(void *);    
    PFUNC pFunc = (PFUNC)&Super::print;
    pFunc(obj);
    
    delete obj;
}
virtual void Super::print ( ) const
Цитата Сообщение от ForEveR Посмотреть сообщение
Убежденный, Ой-ой-ой. Поправьте, если я ошибаюсь, но данный код вполне себе может привести к UB, ибо нигде не гарантируется, что sizeof(function-pointer) == sizeof(pointer to member-function) да и вообще не факт что скомпилируется.
Согласен. Просто не знаю другого способа, удовлетворяющего условию задачи.
А про "operator ->*" - это Вы ловко подметили ;)
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.09.2013, 13:46     Виртуальность и наследование #6
Убежденный, Это непереносимый код (хотя в определенных случаях можно пользоваться и им)...
Да и мой код тоже работает неверно, для начала нужно как-то убить виртуальность.
Kaskera
0 / 0 / 0
Регистрация: 27.07.2013
Сообщений: 34
03.09.2013, 13:48  [ТС]     Виртуальность и наследование #7
Цитата Сообщение от Убежденный Посмотреть сообщение
http://ideone.com/CisVko

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
 
class Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    public: virtual ~Super() {}
};
 
class Sub : public Super {
    public: virtual void print() const {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};
 
int main() {
    Super *obj = new Sub();
    // how to call 'Super::print()' from 'obj'
    // without using operator '.' and/or '->'?
    
    typedef void (*PFUNC)(void *);    
    PFUNC pFunc = (PFUNC)&Super::print;
    pFunc(obj);
    
    delete obj;
}




Согласен. Просто не знаю другого способа, удовлетворяющего условию задачи.
А про "operator ->*" - это Вы ловко подметили
Да, работает, я тоже проверил. Это MSVS 2008 так ругается. Не подскажете, как исправить?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.09.2013, 14:06     Виртуальность и наследование #8
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2013, 14:11     Виртуальность и наследование
Еще ссылки по теме:

Наследование - C++
Тёмного времени суток! Столкнулся с проблемой, основной смысл которой заложен ниже class Parent { void F() = 0; } class...

наследование - C++
во всех подклассах выдает одну и ту же ошибку, что я делаю не так? #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;typeinfo&gt; ...

наследование С++ - C++
Здравствуйте) опять обращаюсь к вам за помощью)) Дано задание: Описать базовый класс CStr – строка. Описать производный от СStr класс...

наследование - C++
Каково состояние бытия выпуклый шестиугольник??? #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;cmath&gt; using namespace...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Kaskera
0 / 0 / 0
Регистрация: 27.07.2013
Сообщений: 34
03.09.2013, 14:11  [ТС]     Виртуальность и наследование #9
Цитата Сообщение от ForEveR Посмотреть сообщение
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
Полностью решения я не видел пока что. Речь идет именно о последнем, как я понимаю, - вызове любого метода через vtable.

Хотя кросс-платформенное решение - это было бы круто!
Yandex
Объявления
03.09.2013, 14:11     Виртуальность и наследование
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru