Const Références à des Pointeurs
Je suis tombé sur un code qui est utilisé une méthode comme ceci:
QList<Item*> itemList;
void addItem(Item* const& item)
{
itemList.append(item);
}
Maintenant, je ne vois aucune différence significative entre ça et ce:
QList<Item*> itemList;
void addItem(Item* item)
{
itemList.append(item);
}
Mais, évidemment, quelqu'un est allé moyen de sortir de leur façon de l'utiliser tel un drôle de type. Ou peut-être un outil de refactoring a horriblement mal tourné.
Est-il une bonne raison de garder que la signature de fonction? Une sorte de cas de coin qui se comporte différemment? Je ne peux pas penser à quelque chose.
Probablement juste un copier-coller à partir de la signature de
Ce n'est pas le passage d'un objet par référence, c'est en passant un pointeur vers un objet. Il n'y aura pas chers de la copie. Je ne peux pas penser à quelque chose, soit, mais peut-être pour l'utilisation de const itérateurs?
Je sais. Je ne dis pas que
Qui est en fait beaucoup de sens. Si un outil de refactoring déduit le type de hors d'usage, vous auriez probablement jusqu'à la fin.
Et btw, en général, il y a des fonctions pour lesquelles il fait une différence - si
QList::append
, qui prend const T&
car il est générique et pour tout ce qu'il sait, T
est cher à copier. Edit: Hé, pas littéralement un copier-coller parce que votre code a T const&
alors que l'intervalle QT docs que j'ai juste vérifié ont const T&
. Mais mentalement une copie, puisque le sens est le même.Ce n'est pas le passage d'un objet par référence, c'est en passant un pointeur vers un objet. Il n'y aura pas chers de la copie. Je ne peux pas penser à quelque chose, soit, mais peut-être pour l'utilisation de const itérateurs?
Je sais. Je ne dis pas que
Item*
pourrait coûter cher à la copie. Je suis en train de dire que, dans QList
, T
pourrait coûter cher à la copie. Ce programmeur a (que je soupçonne), copié du code qui a des préoccupations de pertinence pour le cas spécifique de Item*
. Car il n'y a rien de vraiment mal avec le passage d'un pointeur par const
de référence, ils peuvent même avoir gardé comme ça, délibérément, de sorte qu'il soit compatible avec QList::append
- bien sûr, pour les gens peu familiers avec QList
, c'est incongru puisque vous ne serait pas normalement passer un pointeur de cette façon.Qui est en fait beaucoup de sens. Si un outil de refactoring déduit le type de hors d'usage, vous auriez probablement jusqu'à la fin.
Et btw, en général, il y a des fonctions pour lesquelles il fait une différence - si
addItem
étaient à prendre l'adresse de item
et de la comparer avec d'autres adresses d'ailleurs, puis c'est important de savoir si vous avez une référence à ce que l'appelant est transmise comme argument, ou une copie de celui-ci. Évidemment, dans ce cas, QList::append
ne pas le faire. Donc, il ne s'applique pas ici, mais c'est une raison pour laquelle vous ne pouvez pas simplement aller autour de la aveuglément remplacer toutes les instances de T* const&
avec T*
et s'attendre à ne jamais rien casser. Ainsi que refactoriser outil (si il y en avait un) a droit à un congé de cette façon.OriginalL'auteur cgmb | 2011-03-26
Vous devez vous connecter pour publier un commentaire.
La seule différence est que dans la première version, vous ne seriez pas autorisé à modifier la valeur de la locale
item
l'intérieur de la fonction (que vous pouvez toujours modifier laItem
c'points). Donc si vous voulez unItem*
de tenir une valeur différente pour une raison quelconque, vous 'd être obligé d'utiliser un autre local de typeItem*
et la fonction serait de consommer un supplément desizeof(intptr_t)
octets d'espace de pile (boo hoo).Pas un tremblement de terre, je le sais.
"la fonction serait de consommer un supplément de sizeof(intptr_t) octets d'espace de pile" - si le compilateur a été suffisamment ordures (ou le flux de contrôle suffisamment imprévisible) de ne pas réaliser que
item
peut être zappé au moment où vous cessez de l'utiliser et de commencer à utiliser votre variable supplémentaire.pourquoi n'est-il pas mentionner le fait que le premier élément est une référence dans la présente réponse, seulement que c'est un const? N'est-ce pas aussi une différence
Car il ne font pas une différence pratique dans ce scénario. Et il n'y a aucun point en mentionnant cosmétiques différences.
OriginalL'auteur Jon
C'est une référence à un pointeur const, ce qui signifie que vous obtenez un surnom pour ce pointeur, mais vous ne pouvez pas changer l'adresse qu'il indique.
Un pointeur de copie est équivalent oui, si vous le faites const.
Je sens l'odeur d'une séquence historique des changements obtenu le code à ce point, certainement après plusieurs nommage de refactoring.
OriginalL'auteur Klaim
La première déclaration signifie "élément est un pointeur constant variable de référence". Vous ne pouvez pas changer de point à point à un autre de données de type POINT, et aussi que c'est une référence qui pointe sur le pointeur qui est passé comme un argument dans la fonction appelée.
Pseudo-code:* myItem = new Stylo();
additem(myItem);
première déclaration permet de s'assurer que la fonction additem ne changeront pas la plume de l'objet, car il est une référence constante aussi il l'habitude de copier le contenu de myItem, c'est juste des points à l'emplacement de la mémoire de myItem.
Alors que la deuxième déclaration a une surcharge de copie le contenu de myItem.
OriginalL'auteur Mahesh
C'est une mutable référence à un pointeur constant à une valeur mutable.
La référence devrait vous permettre de modifier quoi que c'est une référence, mais il se trouve que la visée de type est un pointeur constant, de sorte que la valeur du pointeur ne peut pas être changé. La valeur pointée par le pointeur peut être changé.
void* const &
En passant un pointeur constant directement serait équivalent.
void* const
Incorrect. Une mutable référence est une référence où, par le biais de la référence, la valeur peut être muté. Vous faites référence à
reseating
une référence, ce qui n'est pas possible en C++. En tentant de prendre la référence elle-même constante est redondant.Désolé, mais vous avez écrit "mutable référence à un pointeur constant". Qui n'a tout simplement pas de sens. Après la définition de votre commentaire, vous auriez à dire "const référence à un pointeur". Ou vous pourriez correctement dites "de référence à un pointeur const". Mais "mutable référence à un pointeur constant" est juste une pure absurdité.
OriginalL'auteur Sion Sheevok
Une autre différence importante qui se pose à moi est que les données réelles qui sont passés sur la pile. Dans le
Item*
version, unItem*
est passé comme argument, d'avoir besoin d'un déréférencement d'obtenir à laItem
valeur. Cependant, puisque les références sont mis en œuvre lors de la finale en code machine par le passage de pointeurs, leItem* const&
version passe unItem**
comme un argument, d'avoir besoin d' deux déréférence pour obtenir à laItem
valeur.Ce qui explique aussi pourquoi vous auriez besoin de plus d'espace de pile pour obtenir une modifiables
Item*
de la version de Votre appelant n'a pas réellement vous donner unItem*
sur la pile (ou dans un registre) que vous pouvez vous amuser avec, vous n'avez qu'uneItem**
(ouItem* const&
en C++ terre).OriginalL'auteur Matthijs Kooijman