#include <iostream>
using namespace std;
class B {
public:
void invoke(){
cout << "invoke";
}
};
class A{
public:
B* test(){
B b;
auto *bb = &b;
return bb;
}
};
int main() {
A a;
B *b = a.test();
b->invoke();
b->invoke();
return 0;
}
Несколько вопросов по этому коду:
Что такое "корректен"? Не содержит диагностируемых ошибок компиляции? Да, с этой точки зрения код "корректен".
Однако он порождает неопределенное поведение из-за того, что оператор -> выполняет разадресование (indirection) возвращенного a.test() указателя с невалидным значением (invalid pointer value).
А почему он должен ругаться? Никаких нарушений, которые компилятор обязан диагностировать (согласно требованиям спецификации языка), в этом return bb; нет.
Стоит однако помнить, что неопределенное поведение может выражаться и в отказе компилятора компилировать код программы.
Нет, не будет. Хотя работать будет :)
Возврат указателя на локальную переменную некорректен.
Наверное, уровень warning'ов недостаточный... Visual C++ 2017 при /W4 ругается - "возвращение адреса локальной или временной переменной".
В вызове invoke() никак не используется указатель на объект, поэтому ему по барабану, что туда передается, указатель на что... Скорее всего, он будет нормально работать - хотя и не обязан (UB).
Примерно так.
Варианты исправления:
B* test()
{
static B b;
return &b;
}
B* test()
{
return new B;
}
Первый вариант плох тем, что всегда возвращает один и тот же указатель; второй - тем, что потом нужно не забыть удалить созданный объект. Лучше воспользоваться интеллектуальным указателем типа unique_ptr, который его потом сам уничтожит.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости