Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 1
Регистрация: 27.07.2013
Сообщений: 34
1

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

03.09.2013, 12:57. Показов 513. Ответов 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

Покажите свои варианты.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.09.2013, 12:57
Ответы с готовыми решениями:

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

Отбросить виртуальность колбэка
Представьте себе систему которая рассылает события. Нужно запретить клиентам такой системы...

Виртуальность и абстрактные классы. Полиморфизм
На основе этого кода нужно продемонстрировать использование абстрактных классов и виртуальных...

Виртуальность friend-метода в базовом классе
Привет всем. Прошу посмотрите данный код. В производном классе реализована перегрузка оператора...

8
Ушел с форума
Эксперт С++
16427 / 7401 / 1186
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 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);
Ну а как еще вызвать метод объекта, не используя операторы "." и "->" ?
1
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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)();
Операторы ./-> не используются, а про ->*/.* сказано ничего не было.
1
0 / 0 / 1
Регистрация: 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'
0
Ушел с форума
Эксперт С++
16427 / 7401 / 1186
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 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 ->*" - это Вы ловко подметили ;)
0
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
03.09.2013, 13:46 6
Убежденный, Это непереносимый код (хотя в определенных случаях можно пользоваться и им)...
Да и мой код тоже работает неверно, для начала нужно как-то убить виртуальность.
0
0 / 0 / 1
Регистрация: 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 так ругается. Не подскажете, как исправить?
0
В астрале
Эксперт С++
8035 / 4792 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
03.09.2013, 14:06 8
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
0
0 / 0 / 1
Регистрация: 27.07.2013
Сообщений: 34
03.09.2013, 14:11  [ТС] 9
Цитата Сообщение от ForEveR Посмотреть сообщение
Kaskera, К вам вопрос. Вы писали, что есть 1 решение, полагаю вы его видели? Решение кросс-платформенное и написанное на С++? Или же идет игра с таблицей виртуальных функций?
Полностью решения я не видел пока что. Речь идет именно о последнем, как я понимаю, - вызове любого метода через vtable.

Хотя кросс-платформенное решение - это было бы круто!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.09.2013, 14:11

Наследование шаблоном шаблона (наследование конструктора)
Всем привет! Думаю, что эта тема хоть и касается общих вопросов программирования, но будет уместна...

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

Наследование интерфейса и наследование реализации
Начал читать книгу GoF и сразу же в предисловии попал в тупик. Чем отличается наследование...

Наследование С# , наследование полей
В классе есть приватное ПОЛЕ . Мне нужно использовать его в классе потомке . Можно это не сделать...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

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