#c #if-statement #identifier
#c #if-оператор #идентификатор
Вопрос:
P* pFactory(const std::stringamp; pName){
if (p == "s")
SP newP;
else if(pName == "f")
FP newP;
else if(pName == "l")
LP newP;
else if(pName == "i")
IP newP;
else if(pName == "g")
GP newP;
else if (pName == "n")
NP newP;
P* p_ptr = amp;newP;
return nullptr;
}
По сути, предполагается, что функция возвращает указатель на новый объект P, который создается в зависимости от ввода pName. Я получаю сообщение об ошибке использования необъявленного идентификатора ‘newP’ в строке указателя.
Я подумал, что это может быть связано с тем, что нет окончательного else, поэтому объект может никогда не быть создан, но замена последнего else if на else не помогла. Что вызывает эту ошибку?
Редактировать:
P* newP = nullptr;
if (pName== "s")
newP = new SP;
else if(pName == "f")
newP = new FP;
else if(pName == "l")
newP = new LP;
else if(pName == "i")
newP = new IP;
else if(pName == "g")
newP = new GP;
else if (pName == "n")
newP = new NP;
return newP;
будет ли это работать?
Комментарии:
1. Операторы If else имеют свою собственную область видимости, поэтому вы не можете получить доступ к указанным в них переменным. Объявите переменную над блоком if else и присвоите значение внутри if else. Кроме того, получение ссылки на созданный стеком объект и его возврат — это худшее, что вы могли бы сделать, потому что эта переменная выйдет из области видимости после завершения функции.
2. О, я пропустил ту часть в моих инструкциях, в которой говорилось о создании его в куче
3. Как мне объявить его первым? Я ничего не присваиваю newP, просто пытаюсь решить, какой тип P создать. P — это абстрактный класс, а SP, FP, LP и т. Д. Наследуют от P. Возможно ли создать объект и в операторе if else указать, какой тип я хочу, чтобы он был?
4. Кстати, вы всегда возвращаетесь
nullptr
безоговорочно . Не говоря уже о том, что вы получаете указатель на локальные переменные, указатели, которые немедленно станут (или уже являются) недействительными (см. Предыдущий комментарий о области видимости и времени жизни).5. Несколько
return
операторов могут устранить необходимость объявления любых переменных.
Ответ №1:
Операторы If-else имеют собственную область видимости, поэтому вы не можете получить доступ к указанным в них переменным. Объявите переменную над блоком if-else и присвоите значение внутри if-else.
Кроме того, получение ссылки на созданный стеком объект и его возврат — это худшее, что вы могли бы сделать, потому что эта переменная выйдет из области видимости после завершения работы функции, создающей висячий указатель.
Вы можете использовать интеллектуальные указатели, чтобы управлять памятью за вас.
Вот пример того, как это может выглядеть:
#include <string>
#include <memory>
struct P {};
struct A : public P {};
struct B : public P {};
struct C : public P {};
std::unique_ptr<P> pFactory(const std::stringamp; pName)
{
std::unique_ptr<P> p_ptr;
if (pName == "s")
p_ptr = std::make_unique<A>();
else if (pName == "f")
p_ptr = std::make_unique<B>();
else if (pName == "l")
p_ptr = std::make_unique<C>();
return p_ptr;
}
int main()
{
const auto fFactory = pFactory("f");
}
Комментарии:
1. Редактирование вопроса после публикации ответа для предоставления альтернативного ответа в вопросе имеет мало смысла.