在c ++中
class bar
{
int i;
char b;
float d;
};
void foo ( bar arg );
void foo ( bar &arg );
void foo ( bar *arg );
这是一个示例类/结构和函数
我有一些Qs
我知道什么是“在现代编译器和CPU上无关紧要”,但如果我们谈论的是旧CPU或编译器呢?
提前致谢
答案 0 :(得分:22)
指针和引用方法应该具有可比性(速度,内存使用和生成的代码)。
直接传递类会强制编译器复制内存并将bar
对象的副本放在堆栈中。更糟糕的是,在C ++中,存在与此相关的各种讨厌的位(默认的复制构造函数和诸如此类的东西)。
在C中我总是使用(可能是const)指针。在C ++中,您应该使用引用。
答案 1 :(得分:3)
以任何合理的方式通过引用传递可能会导致涉及对象地址的代码。但是,主要的问题是使用引用更加惯用C ++,应该是首选的样式;在你自己的代码中你根本不应该看到很多原始指针。
另请注意,通过引用传递允许被调用者修改参数,通过值和引用传递是根本不同的。如果有的话,您应该将f(bar)
与f(const bar &)
进行比较。
答案 2 :(得分:2)
指针和引用在语法上有所不同,并且在运行时和代码生成中通常是相同的。对于较旧的编译器......我知道Borland 3 C ++ DOS编译器中的一个错误:它在寄存器中缓存了一个int值(通过引用传递),修改了它并且没有更改内存中的原始值。当通过指针传递时,等效代码按预期工作。
但是,我不认为任何现代编译器可能会做这些奇怪的事情(而Borland 5已经解决了这个问题)
至于代码样式(除了指针与智能指针权衡之外),如果地址不能通过函数契约为NULL,我通常使用引用,否则使用指针。
答案 3 :(得分:0)
函数foo可以在案例2和3中修改arg。在第一种情况下,编译器可以优化副本创建,因此很难比较cpu和内存使用情况。
答案 4 :(得分:0)
如果您认为在使用指针参数之前先验证它们是一个好习惯,那么是的,由于引用不需要进行此类测试,因此指针会带来额外的开销。