Sobrecarga de acesso suporte e atribuição C ++
-
06-07-2019 - |
Pergunta
Eu estou escrevendo uma tabela hash para a classe meus dados estruturas, e eu gostaria de adicionar um pouco de açúcar sintático para minha implementação.
template <typename HashedObj, typename Object>
Object & Dictionary<HashedObj, Object>::operator[](HashedObj & key)
{
return items.lookup(key);
}
Esta coima funciona quando eu faço algo como cout << dict [ "MyKey"]. Mas como posso fazer atribuição com os suportes Algo como:?
dict["mykey"] = "something";
E não, isso não faz parte do meu trabalho de casa (sem trocadilhos), eu só quero aprender C ++ um pouco melhor.
Solução
Não está claro o que exatamente você está perguntando aqui. O código que você já apresentou suporta a atribuição. Basta fazê-lo e no trabalho vontade (ou pelo menos deveria compilar). Não faz absolutamente nenhuma diferença de que lado do operador de atribuição seu []
sobrecarregado é usado em. Ele vai trabalhar exatamente da mesma maneira no lado da mão esquerda (LHS) como faz no lado direito (RHS) da cessão (ou como um operando de <<
, como em seu post original). Seu []
retorna uma referência a um Object
, e, em seguida, a atribuição real é tratado pelo operador de atribuição de seu tipo Object
, o que significa que o próprio []
não está realmente envolvido na atribuição actual.
A verdadeira questão aqui é como você quer que seu []
para agir em certos casos especiais. O que vai acontecer se a chave não estiver presente na tabela? Referência ao que Object
é seu lookup
vai voltar neste caso?
É impossibe para descobrir do que você postou. Eu vejo ele retorna uma referência, então retornando NULL
está fora de questão. Será que inserir um novo Object
, vazio para a chave dada? Se assim for, então você não tem que fazer nada. Seu []
já está perfeitamente pronto para ser usado nas LHS do assigment. (Isto é como []
em std::map
funciona, BTW)
No caso do seu lookup
retorna uma referência a um especial Object
"guarda", você tem que tomar medidas especiais. Você provavelmente não quer nada atribuir a um objeto "guarda", então você tem que "desativar" o operador de atribuição de alguma forma e está feito. O resto deve funcionar como é.
Se o seu lookup
lança uma exceção no caso de uma chave inexistente, então você tem que decidir se é isso que você quer quando o []
é usado nas LHS de uma atribuição. Se assim for, então você não precisa fazer nada. Se não, então vai demorar algum trabalho extra ...
Assim, mais uma vez, o que acontece se você passar uma chave inexistente para lookup
?
P.S. Além disso, ele normalmente faz mais sentido para declarar o []
(e lookup
) com qualquer um dos parâmetros const HashedObj&
ou parâmetro HashedObj
apenas. referência não-const, como no seu exemplo, parece estranho e pode levar a problemas em algum (na verdade, na maioria dos casos). Estou surpreso ele funciona para você agora ...
Outras dicas
Você precisa sobrecarga que 2 vezes. Uma que vai ser const
, que será a parte data access
, e que irá retornar uma referência, que irá funcionar como um "setter".
O que você está procurando funcionalidade similar ao operador de suporte sobrecarregado em std::map
. Em std::map
o operador suporte realiza uma pesquisa e retorna uma referência a um objecto associado com uma chave particular. Se o mapa não contém nenhum objeto associado com a chave, o operador insere um novo objeto no mapa usando o construtor padrão.
Então, se você tem std::map<K,V> mymap
, em seguida, chamar mymap[someKey]
vão quer retornar uma referência para o valor associado someKey
, ou então ele irá criar um novo objeto do tipo V
chamando V()
(o construtor padrão de V) e, em seguida, retornar um referência a esse novo objeto, que permite que o chamador para atribuir um valor ao objeto.