对指针的常量引用
我遇到了一些使用这样的方法的代码:
QList<Item*> itemList;
void addItem(Item* const& item)
{
itemList.append(item);
}
现在,我看不出那个和这个之间有任何有意义的区别:
QList<Item*> itemList;
void addItem(Item* item)
{
itemList.append(item);
}
但显然有人不遗余力地使用这样一个奇怪的类型。或者也许重构工具出了严重错误。
有什么充分的理由保留该函数签名吗?某种行为不同的极端情况?我想不出什么。
I came across some code that used a method like this:
QList<Item*> itemList;
void addItem(Item* const& item)
{
itemList.append(item);
}
Now, I can't see any meaningful difference between that and this:
QList<Item*> itemList;
void addItem(Item* item)
{
itemList.append(item);
}
But obviously someone went way out of their way to use such an odd type. Or perhaps a refactoring tool went horribly wrong.
Is there any good reason to keep that function signature? Some sort of corner case that behaves differently? I can't think of anything.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
唯一的区别是,在第一个版本中,您不允许更改函数内本地
item
的值(您仍然可以修改它指向的Item
) 。因此,如果您出于某种原因希望Item*
保存不同的值,您将被迫使用另一个Item*
类型的本地变量,并且该函数将消耗额外的sizeof(intptr_t)
字节的堆栈空间 (boo hoo)。我知道,这并不惊天动地。
The only difference is that in the first version you would not be allowed to change the value of the local
item
inside the function (you could still modify theItem
it points to). Therefore if you wanted anItem*
to hold a different value for some reason, you 'd be forced to use another local of typeItem*
and the function would consume an additionalsizeof(intptr_t)
bytes of stack space (boo hoo).Not earthshaking, I know.
它是对 const 指针的引用,这意味着您会为此指针获得一个昵称,但无法更改它指向的地址。
指针副本是等效的,如果你也将其设置为 const 的话。
我闻到了历史上一系列的变化,这些变化使代码达到了这一点,当然是在多次命名重构之后。
It's a reference to a const pointer, meaning that you get a nickname for this pointer but you can't change the adress it points to.
A pointer copy is equivalent yes, if you make it const too.
I smell a historical sequence of changes that got the code to this point, certainly after several naming refactoring.
第一个声明的意思是“item 是一个常量指针引用变量”。您无法更改该项目以指向 ITEM 类型的另一个数据,而且它也是一个引用,因此它指向在被调用函数中作为参数传递的指针。
伪代码:Item* myItem = new Pen();
添加项目(我的项目);
第一个声明确保 additem 函数不会更改 pen 对象,因为它是一个常量引用,也不会复制 myItem 的内容,它只是指向 myItem 的内存位置。
而第二个声明有复制 myItem 内容的开销。
The first declaration means "item is a constant pointer reference variable". You cant change the item to point to another data of type ITEM, and also it's a reference so it points to the pointer which is passed as an argument in the called function.
Pseudo code: Item* myItem = new Pen();
additem(myItem);
first declaration makes sure that the additem function wont change the pen object since it is a constant reference also it wont copy the contents of myItem, it just points to the memory location of myItem.
Whereas second declaration has an overhead of copying the content of myItem.
它是对指向可变值的常量指针的可变引用。
引用允许您修改它所引用的任何内容,但碰巧引用的类型是常量指针,因此指针的值无法更改。指针指向的值是可以改变的。
void* const &
直接传递常量指针是等效的。
void* const
It is a mutable reference to a constant pointer to a mutable value.
The reference would allow you to modify whatever it is a reference of, but it just so happens the referred type is a constant pointer, so the value of the pointer can't be changed. The value pointed to by the pointer can be changed.
void* const &
Passing a constant pointer directly would be equivalent.
void* const
我发现的另一个显着差异是在堆栈上传递的实际数据。在
Item*
版本中,Item*
作为参数传递,需要一次取消引用才能获取Item
值。但是,由于引用是通过传递指针在最终机器代码中实现的,因此Item* const&
版本实际上传递Item**
作为参数,需要两个 取消引用以获取Item
值。这也解释了为什么您需要额外的堆栈空间来获取可修改的
Item*
版本 - 您的调用者实际上并没有在堆栈上(或在一个寄存器),你可以乱搞,你只有一个Item**
(或者在 C++ 领域中的Item* const&
)。One additional significant difference that occurs to me is that the actual data that is passed on the stack. In the
Item*
version, anItem*
is passed as an argument, needing one dereference to get at theItem
value. However, since references are implemented in the final machine code by passing pointers, theItem* const&
version actually passes anItem**
as an argument, needing two dereferences to get at theItem
value.This also explains why you'd need extra stack space to get a modifiable
Item*
version - Your caller didn't actually give you anItem*
on the stack (or in a register) that you can mess around with, you only have aItem**
(orItem* const&
in C++ land).可能是从模板复制的。
我想创建一个通用类来计算哈希值。
intHash:设置参数为常量
structHash:将签名更改为引用
structPtrHash:它编译的唯一方法
我达到了这个寻找“对常量指针的引用”的任务,
这在我的代码中没有实现。
此问题的热门评论:
const 和 const 有什么区别int*、const int * const 和 int const *?
推荐:
顺时针/螺旋规则
cdecl.org
我的案例的正确模式:
Might have been copied from a template.
I wanted to make a generic class to calculate hashes.
intHash: set the parameter as constant
structHash: changed the signature to reference
structPtrHash: the only way it would compile
I reached this questing looking for "reference to a pointer of a constant",
which was not achieved in my code.
The top comments of this question:
What is the difference between const int*, const int * const, and int const *?
recommends:
Clockwise/Spiral Rule
cdecl.org
The correct pattern for my case: