Russian Qt Forum
Ноябрь 23, 2024, 07:58 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Прелестно  (Прочитано 22146 раз)
OKTA
Гость
« : Сентябрь 30, 2014, 17:19 »

Нашел прелестную вещь, о которой не знал  Веселый
Как думаете, что вылетит в дебаг?  Смеющийся
Код
C
class Foo
{
public:
   Foo() { qDebug() << "Foo()"; }
   void test() { qDebug() << "AHAHAHA";}
   ~Foo() { qDebug() << "~Foo";}
};
 
int main(int argc, char *argv[])
{
   Foo *foo = (Foo*)28;
   foo->test();
   return 0;
}

Даже так работает. Ломает мое представление о мире.
Код
C++ (Qt)
Foo *foo;
   foo->test();
« Последнее редактирование: Сентябрь 30, 2014, 17:23 от OKTA » Записан
Bepec
Гость
« Ответ #1 : Сентябрь 30, 2014, 17:28 »

Я пару раз так тестировал. Ничего особенного, просто не создавайте переменных и ничего не вылетит Улыбающийся

PS жду аргументированных объяснений почему так. Ибо сам не знаю, но пользуюсь Веселый
Записан
OKTA
Гость
« Ответ #2 : Сентябрь 30, 2014, 17:29 »

Да это из серии "вопросы на собеседовании по С++"  Смеющийся
Как вызвать не статическую функцию без создания экземпляра класса?

P.S. Сам не знаю, Верес  Смеющийся
« Последнее редактирование: Сентябрь 30, 2014, 17:33 от OKTA » Записан
Bepec
Гость
« Ответ #3 : Сентябрь 30, 2014, 17:37 »

Можешь ещё жутче поизгаляться. Можно написать полностью консольное приложение на пустом указателе. Главное я уже написал - не создавать переменных Улыбающийся

PS лично у меня пустота на месте знаний - как собственно работает вызов функции класса. Нигде этот момент не акцентируется Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Сентябрь 30, 2014, 17:42 »

Нужно вспомнить, что из себя представляет метод класса и как ему передаётся this. Ничего удивительного нет. Попробуйте в методе test распечатывать значение this и все станет понятно. Улыбающийся
Записан
OKTA
Гость
« Ответ #5 : Сентябрь 30, 2014, 17:45 »

так что запишешь в Foo *foo, то и распечатает) Ставишь 0 - дает 0  Непонимающий Понятнее не стало  Смеющийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Сентябрь 30, 2014, 17:49 »

так что запишешь в Foo *foo, то и распечатает) Ставишь 0 - дает 0  Непонимающий Понятнее не стало  Смеющийся
Метод класса это обычная функция, которой первым параметром передаётся адрес размещения объекта (this). Ваша функция ничего ужасного с объектом не делает, вот если вы по адресу писать начнете, тогда начнутся чудеса.
Записан
Bepec
Гость
« Ответ #7 : Сентябрь 30, 2014, 17:57 »

Теперь пустота заполнилась Улыбающийся Благодарю.

Правильно я говорил что программирование - на 90% обман Улыбающийся

to OKTA: собственно не создавая переменные в классе, мы его не трогаем получается. Так что обращения по невалидному нет. Улыбающийся
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #8 : Сентябрь 30, 2014, 21:00 »

Метод класса это обычная функция, которой первым параметром передаётся адрес размещения объекта (this). Ваша функция ничего ужасного с объектом не делает, вот если вы по адресу писать начнете, тогда начнутся чудеса.

Это не совсем так.

По стандарту обращение к функциям-членам класса по невалидному указателю - это UB.
А это значит, что программу может заглючить независимо от того, что делает функция-член.

Например, если класс полиморфный, то из-за невалидного указателя получается, что скрытый указатель на таблицу виртуальных функций тоже невалиден. Поэтому, вызов виртуальной функции-члена по невалидному указателю скорее всего приведет процесс к крашу.

Вообще, на плюсах есть четкое разделение на так называемые "сишные структуры", они же - POD-типы.
И на "полноценные классы".

Фундаментальное отличие между ними заключается в том, что теоретически компилятор имеет право засунуть в "полноценный" класс любую свою отсебятину.

Сегодня - это скрытый указатель на таблицу виртуальных функций.  Завтра запилят рефлексию, и компилятор добавит ещё что нибудь.

В этих условиях безопасность вызова "казалось бы ничего страшного не делающей" функции-члена - под вопросом.

В любом случае нельзя закладываться на работоспособность функции-члена, которая запускается через объект, который находится в некорректном состоянии.
« Последнее редактирование: Сентябрь 30, 2014, 21:06 от _Bers » Записан
Bepec
Гость
« Ответ #9 : Сентябрь 30, 2014, 21:06 »

Можно сократить до одного предложения.

Использовать сейчас можно, но никто не даёт гарантий. Собственно как и любую возможность с++ Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Сентябрь 30, 2014, 21:08 »

Использовать сейчас можно, но никто не даёт гарантий.
Не представляю где это можно использовать. Улыбающийся
Записан
Bepec
Гость
« Ответ #11 : Сентябрь 30, 2014, 21:22 »

Ну лично я использовал когда строил архитектуру. Можно наплодить десятки и сотни классов без инициализации и проверить собственно архитектурку. И нет нужды описывать всё.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Сентябрь 30, 2014, 21:28 »

Ну лично я использовал когда строил архитектуру. Можно наплодить десятки и сотни классов без инициализации и проверить собственно архитектурку. И нет нужды описывать всё.
Строит глазки
Не обижайтесь, но вы написали просто набор слов. Улыбающийся
Что такое "десятки и сотни классов без инициализации" и как с помощью этого можно проверить "архитектурку"?
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #13 : Сентябрь 30, 2014, 21:39 »

Можно сократить до одного предложения.

Использовать сейчас можно, но никто не даёт гарантий. Собственно как и любую возможность с++ Улыбающийся

Стандарт гарантирует вам корректность некоторых возможностей.
И соответственно компиляторы, которые действуют по стандарту.

Никто не дает никаких гарантий на возможности, которые либо вообще не были описаны в стандарте, либо явно там обозначены, как UB.

Ситуация приведенная в сабже описана в стандарте, как UB.
« Последнее редактирование: Сентябрь 30, 2014, 21:46 от _Bers » Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #14 : Сентябрь 30, 2014, 22:08 »

Использовать сейчас можно, но никто не даёт гарантий.
Не представляю где это можно использовать. Улыбающийся

Код
C++ (Qt)
class MyClass
{
public:
   QString toString() const
   {
       if (this)
           return field_;
       else
           return QString();
   }
private:
   QString field_;
};
 
Записан

Гугль в помощь
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.345 секунд. Запросов: 23.