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

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

Войти
Регистрация
Восстановить пароль
 
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
#1

Указатель this и виртуальние функции - C++

02.05.2014, 20:01. Просмотров 279. Ответов 7
Метки нет (Все метки)

Доброго времени суток!
Есть проблема:
Существует два класса: второй наследует первого.
Есть функция, которая выводит название класса к которому принадлежит объект. Вот в этом и проблема: вызывая данную функцию с второго (наследуемого) класса выводится название первого (родительского).
Как сделать так, чтоб все выводилось правильно без переопределения метода?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class SuperClass {
public: 
    virtual std::string getClassName() {
        return typeid(this).name();
    }
}
 
class SubClass : public SuperClass {}
 
int main() {
    SubClass* object = new SubClass();
    cout << object.getClassName(); // выводит "class SuperClass", а должно "class SubClass"
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.05.2014, 20:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатель this и виртуальние функции (C++):

Реализация двоичных деревьев поиска: Зачем в параметрах функции используется указатель на указатель - C++
Всем привет, встретил в книге такой пример добавления узла в дерево: typedef struct tree { int data; tree *left, *right,...

Указатель на указатель, функции для создания новых массивов? - C++
Всем привет! У меня в коде есть несколько новых массивов, чтобы не повторяться я создам функцию которая будет выделять память под новые...

Объяснить работу функции, возвращающей указатель на указатель на char - C++
Добрый день! Сможете объяснить что означает запись char **InputFile(int &amp;strings);? Почему именно двойное **? Буду очень благодарна...

Реализовать 3 функции, каждая из которых принимает указатель на массив и количество элементов и возвращает указатель на новый массив. - C++
Пишу в Microsoft Visual Studio -&gt;Win32 Console application -&gt;C++. Условие:Реализовать 3 функции, каждая из которых принимает указатель на...

Работа с файлом (передать указатель на файл в функцию, вернуть указатель на файл из функции) - C++
Подскажите как передать указатель на файл в функцию, как вернуть указатель на файл из функции. void Open() // из этой функции вернуть...

Вызов родовой функции (нужно передать массив в качестве аргумента функции через указатель) - C++
#include &lt;iostream&gt; using namespace std; template &lt;class T1&gt; class mas { public: T1 n; T1 a; void input() ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
02.05.2014, 20:06 #2
Функцию переопределите в SubClass.
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
02.05.2014, 20:08 #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Применить typeid к разыменованному указателю:
C++
1
2
3
4
5
6
class SuperClass {
public: 
    virtual std::string getClassName() {
        return typeid(*this).name();
    }
};
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
02.05.2014, 20:10  [ТС] #4
0x10, все работает! Спасибо.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.05.2014, 01:13 #5
Цитата Сообщение от 0x10 Посмотреть сообщение
Применить typeid к разыменованному указателю:
Как я понимаю, всё дело в том, что
this - не явлется glvalue, a *this - является.

a) If expression is a glvalue expression that identifies an object of a polymorphic type (that is, a class that declares or inherits at least one virtual function), the typeid expression evaluates the expression and then refers to the std::type_info object that represents the dynamic type of the expression. If the result of the evaluated expression is a null pointer, an exception of type std::bad_typeid or a type derived from std::bad_typeid is thrown.

b) If expression is not a glvalue expression of polymorphic type, typeid does not evaluate the expression, and the std::type_info object it identifies represents the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.
http://en.cppreference.com/w/cpp/language/typeid
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
03.05.2014, 06:12 #6
Цитата Сообщение от Tulosba Посмотреть сообщение
this - не явлется glvalue, a *this - является.
А почему?
glvalue - это lvalue или xvalue. Потому что this не может стоять слева? this явно не xvalue, а что на счет lvalue?
lvalue
An lvalue is an expression that identifies a non-temporary object or a non-member function.
The following expressions are lvalues:
The name of an object or function in scope, regardless of type, such as std::cin or std::endl. Even if the object's type is rvalue reference, the expression consisting of its name is an lvalue expression.
http://en.cppreference.com/w/cpp/lan...value_category

И typeid работает как раз в терминах типов выражений, а не объектов.

Но, если честно, у меня эти категории значений особо в голове не укладываются, и на практике думать в этих терминах не приходилось никогда. По теме рассуждал на бытовом уровне.
Вот есть у нас класс с виртуальной функцией.
C++
1
2
3
4
5
6
class SuperClass {
public: 
    virtual std::string getClassName() {
        return typeid(*this).name();
    }
};
Где метод getClassName - по сути
C++
1
std::string SuperClass_getClassName(SuperClass* const this)
В дочернем классе метод не переопределен, поэтому и сигнатура остается прежней. Очевидно, что тип this - указатель на SuperClass. Фактически же в примере он указывает на объект типа SubClass, следовательно, выражение *this вернет объект этого типа.

Мб в логике и есть огрехи, но на таком уровне воспринимать достаточно просто.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.05.2014, 13:36 #7
Цитата Сообщение от 0x10 Посмотреть сообщение
А почему?
По стандарту: 9.3.2 The this pointer
1. In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. ...
Цитата Сообщение от 0x10 Посмотреть сообщение
Мб в логике и есть огрехи, но на таком уровне воспринимать достаточно просто.
Хорошо, когда логика стыкуется со стандартом
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
03.05.2014, 13:42 #8
Цитата Сообщение от Tulosba Посмотреть сообщение
Хорошо, когда логика стыкуется со стандартом
Перечитал еще раз пункт b - да, по сути то же самое, что я и говорил, просто я говорил для частного примера, а там написано в общем случае.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2014, 13:42
Привет! Вот еще темы с ответами:

Получить указатель из функции и использовать его в другой функции - C++
Подскажите пожалуйста как из функции использовать в функции main указатель? пример void foo1() {u=sizeof(str1); int *l=&amp;u; } ...

Как получить ссылку на указатель или указатель на указатель в массиве? - C++
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

Указатель на функции - C++
Написать программу-калькулятор, позволяющий выполнять арифметические действия (сложение, вычитание, умножение, деление, взятие остатка от...

Указатель на шаблон функции - C++
Доброй ночи всем! Есть шаблон функции сравнения двух чисел: template &lt;typename _Tp&gt; bool comp(_Tp &amp; a, _Tp &amp; b) { return (a &gt;=...


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

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

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