我知道关于const正确性的问题很少,其中声明函数的声明及其定义不需要同意值参数.这是因为值参数的常量仅在函数内部很重要.这可以:
// header
int func(int i);
// cpp
int func(const int i) {
return i;
}
Run Code Online (Sandbox Code Playgroud)
这样做真的是最好的做法吗?因为我从未见过有人这样做过.我已经在其他地方看过这个引用(不确定来源),这已被讨论过:
"事实上,对于编译器,无论是否在值参数前面包含此const,函数签名都是相同的."
"避免在函数声明中使用const值传递参数.如果不修改参数const,则仍然将参数const置于同一函数的定义中."
第二段说不要将const放在声明中.我假设这是因为值参数的常量作为接口定义的一部分是没有意义的.这是一个实现细节.
根据这个建议,是否也建议指针参数的指针值?(它对参考参数没有意义,因为您无法重新分配参考.)
// header
int func1(int* i);
int func2(int* i);
// cpp
int func1(int* i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compiles without error
return *i;
}
int func2(int* const i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compile error
return *i; …Run Code Online (Sandbox Code Playgroud) 我想知道我的构造者最好的形式.以下是一些示例代码:
class Y { ... }
class X
{
public:
X(const Y& y) : m_y(y) {} // (a)
X(Y y) : m_y(y) {} // (b)
X(Y&& y) : m_y(std::forward<Y>(y)) {} // (c)
Y m_y;
}
Y f() { return ... }
int main()
{
Y y = f();
X x1(y); // (1)
X x2(f()); // (2)
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这是编译器在每种情况下都能做到的最好的.
(1a)y被复制到x1.m_y(1份)
(1b)将y复制到X的构造函数的参数中,然后复制到x1.m_y(2个副本)
(1c)y移入x1.m_y(1移动)
(2a)将f()的结果复制到x2.m_y(1份)
(2b)将f()构造成构造函数的参数,然后复制到x2.m_y(1个副本)
(2c)在堆栈上创建f(),然后移入x2.m_y(1 move)
现在几个问题:
在这两个方面,传递const引用并不差,有时候比传递值更好.这似乎违背了"想要速度?通过价值"的讨论..对于C++(不是C++ 0x),我应该坚持使用const引用作为这些构造函数,还是应该通过值传递?对于C++ 0x,我应该通过rvalue引用传递值吗?
对于(2),如果临时直接构造成x.m_y,我更喜欢.我认为即使是rvalue版本也需要一个移动,除非对象分配动态内存,否则移动与复制一样多.有没有办法对此进行编码,以便允许编译器避免这些副本和移动?
我已经在我认为编译器可以做得最好的事情和我自己的问题中做了很多假设.如果不正确,请更正其中任何一项.
C和C++开发人员使用短语"通过引用传递",但它们似乎用于表示不同的东西.每种语言中这个模棱两可的短语究竟有什么区别?
让我们考虑一个对象foo(可能是一个int,一个double,一个习惯struct,一个class,等等).我的理解是,通过foo引用函数(或只是传递指针foo)来传递更高的性能,因为我们避免制作本地副本(如果foo很大则可能很昂贵).
但是,从这里的答案来看,似乎64位系统上的指针实际上可以预期大小为8字节,无论指向什么.在我的系统上,a float是4个字节.这是否意味着如果foo是类型float,那么仅通过值传递而不是给它指向它是更有效的foo(假设没有其他约束可以使得使用一个比函数内的另一个更有效)?
c++ pointers pass-by-reference pass-by-value pass-by-pointer
目标
我想动态地将事件处理程序分配给整个站点的页面上的某些div.
我的方法
我使用jQuery绑定匿名函数作为选定div事件的处理程序.
问题
代码迭代div名称和相关URL的数组.div名称用于设置绑定目标,即将此事件处理程序附加到此div事件.
当事件处理程序成功绑定到每个div事件时,由这些事件处理程序触发的操作只会定位到数组中的最后一项.
所以我的想法是,如果用户将鼠标放在给定的div上,它应该为该div运行一个滑出动画.但相反,鼠标悬停在div1(rangeTabAll)上会触发div4的滑出动画(rangeTabThm).对于div 2,3等也是如此.顺序并不重要.更改数组元素,事件将始终以数组div4中的最后一个元素为目标.
我的代码 - (使用jQuery)
var curTab, curDiv;
var inlineRangeNavUrls=[['rangeTabAll','range_all.html'],['rangeTabRem','range_remedial.html'],
['rangeTabGym','range_gym.html'],['rangeTabThm','range_thermal.html']];
for (var i=0;i<inlineRangeNavUrls.length;i++)
{
curTab=(inlineRangeNavUrls[i][0]).toString();
curDiv='#' + curTab;
if ($(curDiv).length)
{
$(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);} );
$(curDiv).bind("mouseout", function(){showHideRangeSlidingTabs(curTab, false);} );
}
}
Run Code Online (Sandbox Code Playgroud)
我的理论
我要么没有看到一个令人眼花缭乱的语法错误或它的引用问题.最初我有以下语句来设置curTab的值:
curTab=inlineRangeNavUrls[i][0];
Run Code Online (Sandbox Code Playgroud)
因此,当发生问题我计算过,我改变了(通过for循环迭代)的参考curTab,我实际上改变了以前所有的匿名函数事件处理新curTab价值,以及参考....这是为什么事件处理程序始终以最后一个div为目标.
所以我真正需要做的是将curTab 值传递给匿名函数事件处理程序而不是curTab 对象引用.
所以我认为:
curTab=(inlineRangeNavUrls[i][0]).toString();
Run Code Online (Sandbox Code Playgroud)
会解决问题,但事实并非如此.同样的交易.所以很明显我错过了关于这个问题的一些关键,也许是非常基本的知识.谢谢.
javascript closures anonymous-function pass-by-reference pass-by-value
我应该在什么情况下更喜欢传递参考?传递的价值?
在 C 中,绝对值函数(接受浮点数)的原型是
float fabsf( float );
Run Code Online (Sandbox Code Playgroud)
为什么这个原型不接受一个常量值,像这样:
float fabsf( float const );
Run Code Online (Sandbox Code Playgroud)
fabsf 不会改变输入的值,是吗?
如果我有一个接受输入并调用 fabsf 的函数,我是否被迫避免将输入指定为 const?
在这种情况下处理常量正确性的适当方法是什么?
数组是否默认通过ref或value传递?谢谢.
我刚刚阅读了经典书籍"Effective C++,3rd Edition",在第20项中,作者得出结论,内置类型,STL迭代器和函数对象类型更适合于传值.我完全理解内置函数和迭代器类型的原因,但为什么函数对象应该是值传递,因为我们知道它仍然是类类型的?
pass-by-value ×10
c++ ×8
c ×2
function ×2
pointers ×2
arrays ×1
closures ×1
constants ×1
constructor ×1
javascript ×1
rvalue ×1
terminology ×1