Как я могу уменьшить указатель после прохождения его через функцию? - PullRequest
2 голосов
/ 25 июня 2019

Я создал функцию, которая возвращает базовый указатель на производный объект, который создается в функции.Кажется, это не работает!Как будто производные данные потеряны, а указатель указывает на базовый объект ...

Существует класс Request, который является базовым классом, и класс loginRequest, который выводит Request.Чтобы проверить тип объекта, я напечатал имя объекта (typeid (* r) .name ()).Внутри функции func () вывод на печать оказался «loginRequest», что хорошо, потому что это остроконечный объект.(посмотрите на код) НО после возврата этого указателя, когда я снова печатаю его тип, получается «Запрос».Ребята, можете ли вы помочь мне?почему возвращенный указатель теряет производные данные?


Request * r = new Request();
r = func(); // r is now supposed to point the LoginRequest object.
std::cout<< typeid(*r).name() <<std::endl; //print the type of OBJECT

//func
Request * func()
{
    Request * r;
    LoginRequest l = LoginRequest();
    r = &l;
    std::cout<< typeid(*r).name() <<std::endl;  //print the type of OBJECT
    return r; 
}

Ответы [ 2 ]

3 голосов
/ 25 июня 2019

Вы возвращаете указатель на объект, l, который имеет автоматическую продолжительность хранения.
Разыменование возвращаемого указателя имеет неопределенное поведение.

Вам необходимо создать этот объект динамически с помощью new и удалите утечку памяти, вызванную неправильным использованием new вне функции:

Request* func()
{
    Request* r = new LoginRequest();
    std::cout<< typeid(*r).name() <<std::endl;  //print the type of OBJECT
    return r; 
}


// ...

Request * r = func();
std::cout << typeid(*r).name() << std::endl; //print the type of OBJECT
1 голос
/ 25 июня 2019

Вы создаете локальный LoginRequest объект:

LoginRequest l = LoginRequest();

взяв этот адрес:

r = &l;

и возвращаем его:

return r;

но l выходит за рамки следующей строки:

}

Вместо этого вы хотите создать его в куче:

Request * func()
{
    Request * r;
    LoginRequest* l = new LoginRequest();
    r = l;
    std::cout<< typeid(*r).name() <<std::endl;  //print the type of OBJECT
    return r; 
}

Также используйте умные указатели, а не сырые указатели.

...