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

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

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

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

03.09.2013, 12:57. Просмотров 365. Ответов 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++
Чем отличается перегрузка от виртуальности?

Заменить наследование классов на наследование интерфейсов - C++
#include &lt;iostream&gt; #include &lt;assert.h&gt; using namespace std; int people_on_base = 100; int vehicles_on_base = 100; double...

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

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

Наследование - C++
Добрый вечер! Ребята, почему в данном примере #include &lt;iostream&gt; using namespace std; ...

наследование в С++ - C++
Добрый вечер. относительно недавно мною была получена задача, а точнее несколько задач в одной...И как это ни печально звучит, проблемы...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Убежденный
Системный программист
Эксперт С++
15511 / 7009 / 1108
Регистрация: 02.05.2013
Сообщений: 11,441
Завершенные тесты: 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 / 321
Регистрация: 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'
Убежденный
Системный программист
Эксперт С++
15511 / 7009 / 1108
Регистрация: 02.05.2013
Сообщений: 11,441
Завершенные тесты: 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 / 321
Регистрация: 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 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.09.2013, 14:06 #8
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
Kaskera
0 / 0 / 0
Регистрация: 27.07.2013
Сообщений: 34
03.09.2013, 14:11  [ТС] #9
Цитата Сообщение от ForEveR Посмотреть сообщение
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
Полностью решения я не видел пока что. Речь идет именно о последнем, как я понимаю, - вызове любого метода через vtable.

Хотя кросс-платформенное решение - это было бы круто!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2013, 14:11
Привет! Вот еще темы с ответами:

наследование - C++
помогите пожалуйсто дописать класс многоугольников , и рисовать на монитор с помощью mfc , заранее благодарен... class figure{ public: ...

Наследование - C++
Добрый день. Мне нужно реализовать такую структуру классов: есть класс 1, от него наследуются три класса: 2.1, 2.2, 2.3. От этих трех...

Наследование - C++
Ребят всем привет.Дайте задание для проверки знаний наследования и виртуальных функций,посложнее.

наследование - C++
в чём ошибка (посмотрите рисунок) #include &lt;iostream&gt; #include &quot;stdlib.h&quot; #include &lt;string&gt; using namespace std; char...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
03.09.2013, 14:11
Ответ Создать тему
Опции темы

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