Eu sou muito novo em C ++, então tendo a projetar com muitos Java-ismos enquanto estou aprendendo. De qualquer forma, em Java, se eu tivesse uma classe com um método de 'pesquisa' que retornasse um objeto T
de um Collection< T >
que correspondesse a um parâmetro específico, eu retornaria esse objeto e se o objeto não fosse encontrado na coleção, eu retornaria null
. Então, em minha função de chamada, eu apenas verificariaif(tResult != null) { ... }
Em C ++, estou descobrindo que não posso retornar um null
valor se o objeto não existir. Eu só quero retornar um 'indicador' do tipo T que notifica a função de chamada que nenhum objeto foi encontrado. Não quero lançar uma exceção porque não é realmente uma circunstância excepcional.
É assim que meu código se parece agora:
class Node {
Attr& getAttribute(const string& attribute_name) const {
//search collection
//if found at i
return attributes[i];
//if not found
return NULL; // what should this be?
}
private:
vector<Attr> attributes;
}
Como posso alterá-lo para dar esse tipo de marcador?
fonte
std::find(first, last, value)
retornalast
se nenhum elemento corresponder.Respostas:
Em C ++, as referências não podem ser nulas. Se quiser retornar nulo opcionalmente se nada for encontrado, você precisará retornar um ponteiro, não uma referência:
Caso contrário, se você insiste em retornar por referência, deve lançar uma exceção se o atributo não for encontrado.
(A propósito, estou um pouco preocupado com o seu método ser
const
e retornar um não-const
atributo. Por razões filosóficas, sugiro retornarconst Attr *
. Se você também quiser modificar esse atributo, pode sobrecarregar com um não-const
método retornando um não-const
atributo também.)fonte
nullptr
vez deNULL
para c ++ 11 agora?Existem várias respostas possíveis aqui. Você deseja devolver algo que pode existir. Aqui estão algumas opções, desde a minha menos preferida até a mais preferida:
Retorne por referência e o sinal não pode ser encontrado por exceção.
É provável que não localizar atributos seja uma parte normal da execução e, portanto, não muito excepcional. O manuseio para isso seria barulhento. Um valor nulo não pode ser retornado porque é um comportamento indefinido ter referências nulas.
Retorno por ponteiro
É fácil esquecer de verificar se um resultado de getAttribute seria um ponteiro não NULL e é uma fonte fácil de bugs.
Use Boost.Optional
Um boost :: optional significa exatamente o que está acontecendo aqui, e possui métodos fáceis para inspecionar se tal atributo foi encontrado.
Nota lateral: std :: optional foi recentemente votado em C ++ 17, então isso será uma coisa "padrão" em um futuro próximo.
fonte
boost::optional
não envolve muita sobrecarga (sem alocação dinâmica), por isso é tão bom. Usá-lo com valores polimórficos requer referências ou ponteiros de agrupamento.Você pode criar facilmente um objeto estático que representa um retorno NULL.
E em algum lugar em um arquivo de origem:
fonte
Se você deseja um
NULL
valor de retorno, você precisa usar ponteiros em vez de referências.As referências não podem ser
NULL
.(Nota para os futuros postadores de comentários: Sim, você pode fazer com que o endereço de uma referência seja NULL se você realmente tentar).
Veja minha resposta aqui para uma lista de diferenças entre referências e ponteiros .
fonte
Como você percebeu, não pode fazer da maneira que fazia em Java (ou C #). Aqui está outra sugestão, você poderia passar a referência do objeto como um argumento e retornar o valor bool. Se o resultado for encontrado em sua coleção, você pode atribuí-lo à referência que está sendo passada e retornar 'verdadeiro', caso contrário, retornar 'falso'. Por favor, considere este código.
A função acima deve encontrar o Operador contra a chave 'token', se encontrar o que retorna verdadeiro e atribuir o valor ao parâmetro Operador & op.
O código do chamador para esta rotina se parece com este
fonte
O motivo pelo qual você não pode retornar NULL aqui é porque você declarou seu tipo de retorno como
Attr&
. O trailing&
torna o valor de retorno uma "referência", que é basicamente um ponteiro garantido de não ser nulo para um objeto existente. Se você quiser retornar null, mudeAttr&
paraAttr*
.fonte
Você não pode retornar
NULL
porque o tipo de retorno da função é um objetoreference
e não umpointer
.fonte
Você pode tentar isto:
fonte